#!/data/data/com.termux/files/usr/bin/bash
#
# Termux Desktop
# A simple script to easily install supported desktop environments and
# window managers, along with other essential configurations and tools.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author     : @sabamdarif
# License    : GPL-v3
# Description: This script automates the installation of various desktop environments and window managers
# Repository : https://github.com/sabamdarif/termux-desktop

#########################################################################
#
# Error Handling
#
#########################################################################

# set -euo pipefail

# Global trap handler for cleanup
cleanup_on_exit() {
	local exit_code=$?
	if [ $exit_code -ne 0 ]; then
		log_error "Script exited with error code: $exit_code"
	fi
	# Add any cleanup tasks here
	return $exit_code
}

# Set up trap for cleanup
trap cleanup_on_exit EXIT

#########################################################################
#
# Configuration Constants
#
#########################################################################

# Main variables
readonly REPO_OWNER="sabamdarif"
readonly REPO_NAME="termux-desktop"
readonly REPO_BRANCH_MAIN="main"
readonly REPO_SETUP_FILE_BRANCH="setup-files"
readonly REPO_SETUP_FILES_FOLDER="setup-files"
readonly REPO_RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}"
readonly TERMUX_HOME=${HOME:-/data/data/com.termux/files/home}
readonly TERMUX_PREFIX=${PREFIX:-/data/data/com.termux/files/usr}
# Retry configuration
readonly MAX_DOWNLOAD_RETRIES=5
readonly MAX_INSTALL_RETRIES=5
readonly DOWNLOAD_TIMEOUT=15

#########################################################################
#
# Initial Values
#
#########################################################################
readonly TERMUX_DESKTOP_PATH="$TERMUX_PREFIX/etc/termux-desktop"
readonly CONFIG_FILE="$TERMUX_DESKTOP_PATH/configuration.conf"
readonly LOG_FILE="$TERMUX_HOME/termux-desktop.log"
CALL_FROM_CHANGE_DISTRO=false
CALL_FROM_CHANGE_STYLE=false
IS_TERMUX_API_INSTALLED=false
LITE_MODE="${LITE,,}"
#########################################################################
#
# Color Setup
#
#########################################################################
# shellcheck disable=SC2154
if [ -t 1 ] && [ -n "${TERM:-}" ]; then
	R="$(printf '\033[0m\033[1m\033[31m')" # RST + bold + red
	G="$(printf '\033[0m\033[32m')"        # RST + green
	Y="$(printf '\033[0m\033[33m')"        # RST + yellow
	B="$(printf '\033[0m\033[34m')"        # RST + blue
	C="$(printf '\033[0m\033[36m')"        # RST + cyan
	NC="$(printf '\033[0m')"               # RST
	BOLD="$(printf '\033[1m')"             # bold
else
	R=""
	G=""
	Y=""
	B=""
	C=""
	NC=""
	BOLD=""
fi

cd "$TERMUX_HOME" || exit 1

##################################################################
# create detailed log output
function debug_msg() {
	local debug_message="[DEBUG] running: $BASH_COMMAND"
	echo "$debug_message"
	echo "$(date '+%Y-%m-%d %H:%M:%S') - $debug_message" >>"$LOG_FILE"
}

function banner() {
	clear
	printf "%s############################################################\n" "$C"
	printf "%s#                                                          #\n" "$C"
	printf "%s#  ▀█▀ █▀▀ █▀█ █▀▄▀█ █ █ ▀▄▀   █▀▄ █▀▀ █▀ █▄▀ ▀█▀ █▀█ █▀█  #\n" "$C"
	printf "%s#   █  ██▄ █▀▄ █   █ █▄█ █ █   █▄▀ ██▄ ▄█ █ █  █  █▄█ █▀▀  #\n" "$C"
	printf "%s#                                                          #\n" "$C"
	printf "%s######################### Termux Gui #######################%s\n" "$C" "$NC"

	echo " "
}

# check if the script is running on termux or not
# TODO: Need to find a better way to detect termux
function check_termux() {
	if [[ -z "$PREFIX" && "$PREFIX" != *"/com.termux/"* ]]; then
		echo "${R}[${R}☓${R}]${R}${BOLD}Please run it inside termux${NC}"
		exit 1
	fi
}

#########################################################################
#
# Base Functions
#
#########################################################################

function print_log() {
	local timestamp
	timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
	local log_level="${2:-INFO}"
	local message="$1"
	echo "[${timestamp}] ${log_level}: ${message}" >>"$LOG_FILE" 2>/dev/null || true
}

function log_warn() {
	local timestamp
	timestamp=$(date '+%Y-%m-%d %H:%M:%S')
	local message="$1"
	echo "[${timestamp}] WARN: ${message}" >>"$LOG_FILE" 2>/dev/null || true
}

function log_error() {
	local timestamp
	timestamp=$(date '+%Y-%m-%d %H:%M:%S')
	local message="$1"
	echo "[${timestamp}] ERROR: ${message}" >>"$LOG_FILE" 2>/dev/null || true
}

function log_debug() {
	local timestamp
	timestamp=$(date '+%Y-%m-%d %H:%M:%S')
	local message="$1"
	echo "[${timestamp}] DEBUG: ${message}" >>"$LOG_FILE" 2>/dev/null || true
}

function print_success() {
	local msg
	msg="$1"
	echo "${R}[${G}✓${R}]${G} $msg ${NC}"
	log_debug "$msg"
}

function print_failed() {
	local msg
	msg="$1"
	echo "${R}[${R}☓${R}]${R} $msg ${NC}"
	log_debug "$msg"
}

function print_warn() {
	local msg
	msg="$1"
	echo "${R}[${Y}!${R}]${Y} $msg ${NC}"
	log_debug "$msg"
}

function print_msg() {
	local msg
	msg="$1"
	echo "${R}[${C}-${R}]${B} $msg ${NC}"
	log_debug "$msg"

}

function wait_for_keypress() {
	read -n1 -s -r -p "${R}[${C}-${R}]${G} Press any key to continue, CTRL+c to cancel...${NC}"
	echo
}

function check_and_create_directory() {
	if [[ -n "$1" && ! -d "$1" ]]; then
		mkdir -p "$1" 2>/dev/null || {
			log_error "Failed to create directory: $1"
			return 1
		}
		log_debug "Created directory: $1"
	fi
}

# first check then delete
function check_and_delete() {
	local files_folders
	for files_folders in "$@"; do
		if [[ -e "$files_folders" ]]; then
			rm -rf "$files_folders" >/dev/null 2>&1 || {
				log_error "Failed to delete: $files_folders"
				continue
			}
			log_debug "Deleted: $files_folders"
		fi
	done
}

# first check then backup
function check_and_backup() {
	log_debug "Starting backup for: $*"
	# shellcheck disable=SC2206
	local files_folders_list=($@)
	local files_folders
	local date_str
	date_str=$(date +"%d-%m-%Y")

	for files_folders in "${files_folders_list[@]}"; do
		if [[ -e "$files_folders" ]]; then
			local backup="${files_folders}-${date_str}.bak"

			if [[ -e "$backup" ]]; then
				print_msg "Backup $backup already exists"
			else
				print_msg "Backing up $files_folders"
				mv "$files_folders" "$backup"
				log_debug "$files_folders $backup"
			fi
		else
			print_msg "Path $files_folders does not exist"
		fi
	done
}

# find a backup file which end with a number pattern and restore it
function check_and_restore() {
	log_debug "Starting restore for: $*"
	# shellcheck disable=SC2206
	local files_folders_list=($@)
	local files_folders

	for files_folders in "${files_folders_list[@]}"; do
		local latest_backup
		latest_backup=$(find "$(dirname "$files_folders")" -maxdepth 1 -name "$(basename "$files_folders")-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9].bak" 2>/dev/null | sort | tail -n 1)

		if [[ -z "$latest_backup" ]]; then
			print_msg "No backup found for $files_folders"
			continue
		fi

		if [[ -e "$files_folders" ]]; then
			print_msg "File $files_folders already exists"
		else
			print_msg "Restoring $files_folders"
			mv "$latest_backup" "$files_folders"
			log_debug "$latest_backup $files_folders"
		fi
	done
}

function download_file() {
	local dest
	local url
	local max_retries=$MAX_DOWNLOAD_RETRIES
	local attempt=1
	local successful_attempt=0

	if [[ -z "$2" ]]; then
		url="$1"
		dest="$(basename "$url")"
	else
		dest="$1"
		url="$2"
	fi

	if [[ -z "$url" ]]; then
		print_failed "No URL provided!"
		return 1
	fi

	while [[ $attempt -le $max_retries ]]; do
		print_msg "Downloading $dest..."
		if [[ ! -s "$dest" ]]; then
			check_and_delete "$dest"
		fi

		if command -v wget &>/dev/null; then
			wget --tries=5 --timeout=$DOWNLOAD_TIMEOUT --retry-connrefused -O "$dest" "$url"
		else
			curl -# -L "$url" -o "$dest"
		fi

		if [[ -f "$dest" && -s "$dest" ]]; then
			successful_attempt=$attempt
			break
		else
			print_failed "Download failed. Retrying... ($attempt/$max_retries)"
		fi
		((attempt++))
	done

	if [[ -f "$dest" ]]; then
		if [[ $successful_attempt -eq 1 ]]; then
			print_success "File downloaded successfully."
		else
			print_success "File downloaded successfully on attempt $successful_attempt."
		fi
		return 0
	fi

	print_failed "Failed to download the file after $max_retries attempts. Exiting."
	return 1
}

function detect_package_manager() {
	# shellcheck disable=SC1091
	if [[ -f "$TERMUX_PREFIX/bin/termux-setup-package-manager" ]]; then
		source "$TERMUX_PREFIX/bin/termux-setup-package-manager"
	fi

	if [[ "$TERMUX_APP_PACKAGE_MANAGER" == "apt" ]]; then
		PACKAGE_MANAGER="apt"
	elif [[ "$TERMUX_APP_PACKAGE_MANAGER" == "pacman" ]]; then
		PACKAGE_MANAGER="pacman"
	else
		PACKAGE_MANAGER="pkg"
		print_failed "${C} Could not detect your package manager, Switching To ${C}pkg ${NC}"
	fi
	log_debug "Package manager: $PACKAGE_MANAGER"
}

# will check if the package is already installed or not, if it installed then reinstall and print success/failed message
function package_install_and_check {
	log_debug "Starting package installation for: $*"
	local packs_list
	# Properly splits on spaces
	IFS=' ' read -r -a packs_list <<<"$*"

	# pacman part
	if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
		for package_name in "${packs_list[@]}"; do
			if [[ "$package_name" == *"*"* ]]; then
				log_debug "Processing wildcard pattern: $package_name"
				local packages
				packages=$(pacman -Ssq 2>/dev/null | grep -E "^${package_name//\*/.*}$")
				log_debug "matched packages: ${C}$packages"
				for package in $packages; do
					local retry_count=0
					local max_retries=$MAX_INSTALL_RETRIES
					local install_success=false
					while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
						retry_count=$((retry_count + 1))
						check_and_delete "$TERMUX_PREFIX/var/lib/pacman/db.lck"
						print_msg "Installing Package : ${C}$package"
						pacman -S --noconfirm "$package" 2>/dev/null
						if pacman -Qi "$package" >/dev/null 2>&1; then
							print_success "Successfully install package: ${C}$package"
							install_success=true
						else
							print_warn "Failed to install package: ${C}${package}. ${Y}Trying again... ($retry_count)"
						fi
					done
				done
			else
				local retry_count=0
				local max_retries=$MAX_INSTALL_RETRIES
				local install_success=false
				while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
					retry_count=$((retry_count + 1))
					check_and_delete "$TERMUX_PREFIX/var/lib/pacman/db.lck"
					print_msg "Installing Package : ${C}$package_name"
					pacman -S --noconfirm "$package_name" 2>/dev/null
					if pacman -Qi "$package_name" >/dev/null 2>&1; then
						print_success "Successfully install package: ${C}$package_name"
						install_success=true
					else
						print_warn "Failed to install package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
					fi
				done
			fi
		done
	else
		#apt part
		for package_name in "${packs_list[@]}"; do
			if [[ "$package_name" == *"*"* ]]; then
				log_debug "Processing wildcard pattern: $package_name"
				local packages
				packages=$(apt-cache pkgnames 2>/dev/null | grep -E "^${package_name//\*/.*}$" | sort -u)
				log_debug "matched packages: $packages"
				for package in $packages; do
					local retry_count=0
					local max_retries=$MAX_INSTALL_RETRIES
					local install_success=false
					while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
						retry_count=$((retry_count + 1))
						print_msg "Installing package: ${C}$package"
						apt install "$package" -y 2>/dev/null
						if dpkg -s "$package" >/dev/null 2>&1; then
							print_success "Successfully install package: ${C}$package"
							install_success=true
						else
							print_warn "Failed to install package: ${C}${package}. ${Y}Trying again... ($retry_count)"
							# Only run recovery commands on failure
							dpkg --configure -a 2>/dev/null
							apt --fix-broken install -y 2>/dev/null
							apt install --fix-missing -y 2>/dev/null
						fi
					done
				done
			else
				local retry_count=0
				local max_retries=$MAX_INSTALL_RETRIES
				local install_success=false
				while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
					retry_count=$((retry_count + 1))
					print_msg "Installing package: ${C}$package_name"
					apt install "$package_name" -y 2>/dev/null
					if dpkg -s "$package_name" >/dev/null 2>&1; then
						print_success "Successfully install package: ${C}$package_name"
						install_success=true
					else
						print_warn "Failed to install package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
						# Only run recovery commands on failure
						dpkg --configure -a 2>/dev/null
						apt --fix-broken install -y 2>/dev/null
						apt install --fix-missing -y 2>/dev/null
					fi
				done
			fi
		done
	fi
}

# will check the package is installed or not then remove it
function package_check_and_remove() {
	log_debug "Starting package removal for: $*"
	local packs_list
	# Properly splits on spaces
	IFS=' ' read -r -a packs_list <<<"$*"

	if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
		for package_name in "${packs_list[@]}"; do
			if [[ "$package_name" == *"*"* ]]; then
				log_debug "Processing wildcard pattern: $package_name"
				local packages
				packages=$(pacman -Qsq 2>/dev/null | grep -E "^${package_name//\*/.*}$")
				if [[ -z "$packages" ]]; then
					print_success "No installed packages found matching: ${C}$package_name"
					continue
				fi
				log_debug "matched packages: $packages"
				for package in $packages; do
					local retry_count=0
					local max_retries=$MAX_INSTALL_RETRIES
					local remove_success=false
					while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
						retry_count=$((retry_count + 1))
						check_and_delete "$TERMUX_PREFIX/var/lib/pacman/db.lck"
						print_msg "Removing Package : ${C}$package"
						pacman -Rnds --noconfirm "$package" 2>/dev/null
						if ! pacman -Qi "$package" >/dev/null 2>&1; then
							print_success "Successfully removed package: ${C}$package"
							remove_success=true
						else
							print_warn "Failed to remove package: ${C}${package}. ${Y}Trying again...($retry_count)"
						fi
					done
				done
			else
				if pacman -Qi "$package_name" >/dev/null 2>&1; then
					local retry_count=0
					local max_retries=$MAX_INSTALL_RETRIES
					local remove_success=false
					while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
						retry_count=$((retry_count + 1))
						check_and_delete "$TERMUX_PREFIX/var/lib/pacman/db.lck"
						print_msg "Removing Package : ${C}$package_name"
						pacman -Rnds --noconfirm "$package_name" 2>/dev/null
						if ! pacman -Qi "$package_name" >/dev/null 2>&1; then
							print_success "Successfully removed package: ${C}$package_name"
							remove_success=true
						else
							print_warn "Failed to remove package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
						fi
					done
				else
					print_success "Package ${C}$package_name${G} is not installed.${NC}"
				fi
			fi
		done
	else
		for package_name in "${packs_list[@]}"; do
			if [[ "$package_name" == *"*"* ]]; then
				log_debug "Processing wildcard pattern: $package_name"
				local packages
				packages=$(dpkg-query -W -f='${binary:Package}\n' "${package_name}" 2>/dev/null | grep -v ' ')

				if [[ -z "$packages" ]]; then
					print_success "No installed packages found matching: ${C}$package_name"
					continue
				fi

				log_debug "matched packages: $packages"
				for package in $packages; do
					local retry_count=0
					local max_retries=$MAX_INSTALL_RETRIES
					local remove_success=false
					while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
						retry_count=$((retry_count + 1))
						print_msg "Removing package: ${C}$package"
						dpkg --configure -a >/dev/null 2>&1
						apt autoremove "$package" -y 2>/dev/null
						if ! dpkg -s "$package" >/dev/null 2>&1; then
							print_success "Successfully removed package: ${C}$package"
							remove_success=true
						else
							print_warn "Failed to remove package: ${C}${package}. ${Y}Trying again...($retry_count)"
						fi
					done
				done
			else
				if dpkg -s "$package_name" >/dev/null 2>&1; then
					local retry_count=0
					local max_retries=$MAX_INSTALL_RETRIES
					local remove_success=false
					while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
						retry_count=$((retry_count + 1))
						print_msg "Removing package: ${C}$package_name"
						dpkg --configure -a >/dev/null 2>&1
						apt autoremove "$package_name" -y 2>/dev/null
						if ! dpkg -s "$package_name" >/dev/null 2>&1; then
							print_success "Successfully removed package: ${C}$package_name"
							remove_success=true
						else
							print_warn "Failed to remove package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
						fi
					done
				else
					print_success "Package ${C}$package_name${G} is not installed.${NC}"
				fi
			fi
		done
	fi
}

function get_file_name_number() {
	local current_file
	current_file=$(basename "$0")
	local folder_name="${current_file%.sh}"
	local theme_number
	theme_number=$(echo "$folder_name" | grep -oE '[1-9][0-9]*')
	log_debug "Theme number: $theme_number"
	echo "$theme_number"
}

function extract_archive() {
	local archive="$1"
	if [[ ! -f "$archive" ]]; then
		print_failed "$archive doesn't exist"
		return 1
	fi

	case "$archive" in
	*.tar.gz | *.tgz)
		print_success "Extracting ${C}$archive"
		tar xzvf "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.tar.xz)
		print_success "Extracting ${C}$archive"
		tar xJvf "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.tar.bz2 | *.tbz2)
		print_success "Extracting ${C}$archive"
		tar xjvf "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.tar)
		print_success "Extracting ${C}$archive"
		tar xvf "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.bz2)
		print_success "Extracting ${C}$archive"
		bunzip2 -v "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.gz)
		print_success "Extracting ${C}$archive${NC}"
		gunzip -v "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.7z)
		print_success "Extracting ${C}$archive"
		7z x "$archive" -y 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.zip)
		print_success "Extracting ${C}$archive"
		unzip "${archive}" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*.rar)
		print_success "Extracting ${C}$archive"
		unrar x "$archive" 2>/dev/null || {
			print_failed "Failed to extract ${C}$archive"
			return 1
		}
		;;
	*)
		print_failed "Unsupported archive format: ${C}$archive"
		return 1
		;;
	esac
	print_success "Successfully extracted ${C}$archive"
	log_debug "Extracted: $archive"
}

# download a archive file and extract it in a folder
function download_and_extract() {
	local url="$1"
	local target_dir="$2"
	local filename="${url##*/}"

	if [[ -n "$target_dir" ]]; then
		check_and_create_directory "$target_dir"
		cd "$target_dir" || return 1
	fi

	if download_file "$filename" "$url"; then
		if [[ -f "$filename" ]]; then
			echo
			extract_archive "$filename"
			check_and_delete "$filename"
		fi
	else
		print_failed "Failed to download ${C}${filename}"
		print_msg "${C}Please check your internet connection"
	fi
	log_debug "Downloaded and extracted: $url to $target_dir"
}

count_subfolders() {
	local owner="$1"
	local repo="$2"
	local path="$3"
	local branch="$4"
	local response
	response=$(curl -s "https://api.github.com/repos/$owner/$repo/contents/$path?ref=$branch" 2>/dev/null)
	# Use jq to extract directories and count them; if none found then set to 0
	local subfolder_count
	subfolder_count=$(echo "$response" | jq -r '[.[] | select(.type == "dir")] | length' 2>/dev/null)
	echo "${subfolder_count:-0}"
	log_debug "Subfolder count: ${subfolder_count:-0}"
}

# create a yes / no confirmation prompt
function confirmation_y_or_n() {
	while true; do
		# prompt
		read -r -p "${R}[${C}-${R}]${Y} $1 ${Y}(y/n) ${NC}" response
		# apply default
		response="${response:-y}"
		# lowercase
		response="${response,,}"

		# reject spaces or slashes
		if [[ "$response" =~ [[:space:]/] ]]; then
			echo
			print_failed "Invalid input: no spaces or slashes allowed. Enter only 'y' or 'n'."
			echo
			continue
		fi

		# normalize full words to single letters
		if [[ "$response" =~ ^(yes|y)$ ]]; then
			response="y"
		elif [[ "$response" =~ ^(no|n)$ ]]; then
			response="n"
		else
			echo
			print_failed "Invalid input. Please enter 'y', 'yes', 'n', or 'no'."
			echo
			continue
		fi

		# store in the caller's variable
		eval "$2='$response'"

		# handle it
		case $response in
		y)
			echo
			print_success "Continuing with answer: $response"
			echo
			sleep 0.2
			break
			;;
		n)
			echo
			print_msg "${C}Skipping this step${NC}"
			echo
			sleep 0.2
			break
			;;
		esac
	done
	log_debug "Confirmation: $1 - response: $response"
}

# get the latest version from a github releases
# ex. latest_tag=$(get_latest_release "$repo_owner" "$repo_name")
function get_latest_release() {
	local repo_owner="$1"
	local repo_name="$2"
	curl --silent \
		--location \
		--retry 5 \
		--retry-delay 1 \
		-H "Accept: application/vnd.github.v3+json" \
		"https://api.github.com/repos/${repo_owner}/${repo_name}/releases/latest" | jq -r '.tag_name'
}

function install_font_for_style() {
	local style_number="$1"
	print_msg "Installing Fonts..."
	check_and_create_directory "$TERMUX_HOME/.fonts"
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/$de_name/look_${style_number}/font.tar.gz" "$TERMUX_HOME/.fonts"
	fc-cache -f 2>/dev/null
	cd "$TERMUX_HOME" || return 1
}

# Use:- select_an_option 8 1 variable_name
function select_an_option() {
	local max_options=$1
	local default_option=${2:-1}
	local response_var=$3
	local response

	while true; do
		read -r -p "${Y}select an option (Default ${default_option}): ${NC}" response
		response=${response:-$default_option}

		if [[ $response =~ ^[0-9]+$ ]] && ((response >= 1 && response <= max_options)); then
			echo
			print_success "Continuing with answer: $response"
			sleep 0.2
			eval "$response_var=$response"
			break
		else
			echo
			print_failed " Invalid input, Please enter a number between 1 and $max_options"
		fi
	done
}

function read_conf() {
	if [[ ! -f "$CONFIG_FILE" ]]; then
		print_failed " Configuration file $CONFIG_FILE not found"
		exit 0
	fi
	# shellcheck disable=SC1090
	source "$CONFIG_FILE"
	print_success "Configuration variables loaded"
	validate_required_vars
}

# Use atomic write pattern to prevent background execution issues
function print_to_config() {
	local var_name="$1"
	local var_value="${2:-${!var_name}}"
	local IFS=$' \t\n'
	local temp_file="${CONFIG_FILE}.tmp.$$"

	# Ensure config file exists
	if [[ ! -f "$CONFIG_FILE" ]]; then
		touch "$CONFIG_FILE" 2>/dev/null || {
			log_error "Cannot access $CONFIG_FILE"
			return 1
		}
	fi

	if grep -q "^${var_name}=" "$CONFIG_FILE" 2>/dev/null; then
		# Atomic write: write to temp file then move
		sed "s|^${var_name}=.*|${var_name}=${var_value}|" "$CONFIG_FILE" >"$temp_file" && mv "$temp_file" "$CONFIG_FILE"
	else
		echo "${var_name}=${var_value}" >>"$CONFIG_FILE"
	fi

	log_debug "$var_name = $var_value"
}

function validate_required_vars() {
	local required_vars=(
		# Basic system variables
		"HOME"
		"PREFIX"
		"TMPDIR"
		"PACKAGE_MANAGER"
		# Display and GUI variables
		"display_number"
		"gui_mode"
		"de_name"
		"de_startup"
		"de_on_startup"
		# Hardware acceleration variables
		"enable_hw_acc"
		# Configuration paths
		"CONFIG_FILE"
		"themes_folder"
		"icons_folder"
		# apps
		"installed_browser"
		"installed_ide"
		"installed_media_player"
		"installed_photo_editor"
		"installed_wine"
		# extra
		"chosen_shell_name"
		"terminal_utility_setup_answer"
		"fm_tools"
		# Distro
		"distro_add_answer"
	)

	# If hardware acceleration is enabled, add required variables
	if [[ "$enable_hw_acc" == "y" ]]; then
		required_vars+=(
			"GPU_NAME"
			"exp_termux_vulkan_hw_answer"
			"termux_hw_answer"
		)
	fi

	# If a distro is enabled, add required variables
	# shellcheck disable=SC2154
	if [[ "$distro_add_answer" == "y" ]]; then
		required_vars+=(
			"selected_distro_type"
			"selected_distro"
			"pd_audio_config_answer"
			"pd_useradd_answer"
		)
	fi

	# shellcheck disable=SC2154
	if [[ "$distro_add_answer" == "y" ]] && [[ "$pd_useradd_answer" == "y" ]]; then
		required_vars+=(
			"user_name"
		)
	fi

	if [[ "$enable_hw_acc" == "y" ]] && [[ "$distro_add_answer" == "y" ]]; then
		required_vars+=(
			"pd_hw_answer"
		)
	fi

	print_msg "Validating required configuration values..."

	local missing_vars=()
	for var in "${required_vars[@]}"; do
		if [[ -z "${!var}" ]]; then
			missing_vars+=("$var")
		fi
	done

	if ((${#missing_vars[@]} > 0)); then
		print_failed "The following required configuration values are not set:"
		for var in "${missing_vars[@]}"; do
			echo "  - $var"
			log_debug "$var"
			exit 1
		done
		exit 1
	fi

	print_success "All required variables are set"
	return 0
}

#########################################################################
#
# Ask Required Questions
#
#########################################################################

# check the avilable styles and create a list to type the corresponding number
# in the style readme file the name must use this'## number name :' pattern, like:- ## 1. Basic Style:
function questions_theme_select() {
	local owner="$REPO_OWNER"
	local repo="$REPO_NAME"
	local main_folder="$REPO_SETUP_FILES_FOLDER/$de_name"
	local branch="$REPO_SETUP_FILE_BRANCH"

	# Set default style value based on the desktop environment (DE)
	case "$de_name" in
	xfce | mate | i3wm) default_selection="1" ;;
	lxqt | openbox) default_selection="2" ;;
	dwm | bspwm | awesome | fluxbox) default_selection="0" ;;
	*) default_selection="0" ;;
	esac

	# Get the number of available custom styles
	subfolder_count_value=$(count_subfolders "$owner" "$repo" "$main_folder" "$branch" 2>/dev/null)

	# If no custom styles are available, use stock style and skip interaction
	if [[ "$subfolder_count_value" -eq 0 ]]; then
		print_msg "No custom setup is available for $de_name"
		log_debug "no:- $subfolder_count_value, No custom setup is available for $de_name"
		print_msg "Continuing with style 0: Stock"
		style_answer=0
		style_name="Stock"
		log_debug "$style_answer $subfolder_count_value"
		return
	fi

	# If custom styles exist, fetch and display them
	local styles_url="$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/docs/${de_name}_styles.md"
	if curl --head --silent --fail "$styles_url" >/dev/null; then
		print_msg "Downloading list of available styles..."
		check_and_delete "${current_path}/styles.md"
		download_file "${current_path}/styles.md" "$styles_url"
	else
		log_debug "No custom setup is available for $de_name"
		print_msg "Continuing with style 0: Stock"
		style_answer=0
		style_name="Stock"
		log_debug "$style_answer $subfolder_count_value"
		return
	fi

	if [[ "$subfolder_count_value" -gt 0 ]]; then
		banner

		print_msg "Check the $de_name styles preview"
		echo
		print_msg "From Here:- ${B}https://github.com/$REPO_OWNER/$REPO_NAME/blob/$REPO_BRANCH_MAIN/docs/${de_name}_styles.md"
		echo
		print_msg "Number of available custom styles for $de_name is: ${C}${subfolder_count_value}"
		echo
		print_msg "Available Styles Are:"
		echo

		grep -oP '## \d+\..+?(?=(\n## \d+\.|\Z))' "${current_path}/styles.md" | while read -r style; do
			echo "${Y}${style#### }${NC}"
		done

		while true; do
			echo
			read -r -p "${R}[${C}-${R}]${Y} Type number of the style (Press Enter to select default): ${NC}" style_answer
			style_answer="${style_answer:-$default_selection}"

			if [[ "$style_answer" =~ ^[0-9]+$ ]] && [[ "$style_answer" -ge 0 ]] && [[ "$style_answer" -le "$subfolder_count_value" ]]; then
				style_name=$(grep -oP "^## $style_answer\..+?(?=(\n## \d+\.|\Z))" "${current_path}/styles.md" | sed -e "s/^## $style_answer\. //" -e "s/:$//" -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
				echo
				print_success "Continuing with style number ${C}$style_answer (Style: $style_name${NC})"
				echo
				break
			else
				echo
				print_failed "The entered style number is incorrect"
				echo
				print_msg "${Y}Please enter a number between 0 and ${subfolder_count_value}"
				echo
				print_msg "Check the $de_name styles section in GitHub"
				echo
				print_msg "${B}https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/$REPO_BRANCH_MAIN/docs/${de_name}_styles.md"
				echo
			fi
		done

		check_and_delete "${current_path}/styles.md"
		log_debug "$style_answer $subfolder_count_value"
	fi
}

function ask_to_chose_de() {
	# Setlect Desktop Environment
	banner
	print_msg "Importing desktop related data..."
	local owner="${REPO_OWNER}"
	local repo="$REPO_NAME"
	local branch="$REPO_SETUP_FILE_BRANCH"
	# calculate availabe styles for all the desktop environments
	local total_custom_xfce_setup
	total_custom_xfce_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/xfce" "$branch" 2>/dev/null)
	local total_custom_lxqt_setup
	total_custom_lxqt_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/lxqt" "$branch" 2>/dev/null)
	local total_custom_mate_setup
	total_custom_mate_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/mate" "$branch" 2>/dev/null)
	local total_custom_gnome_setup
	total_custom_gnome_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/gnome" "$branch" 2>/dev/null)
	local total_custom_cinnamon_setup
	total_custom_cinnamon_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/cinnamon" "$branch" 2>/dev/null)
	# calculate availabe styles for all the window managers
	local total_custom_openbox_setup
	total_custom_openbox_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/openbox" "$branch" 2>/dev/null)
	local total_custom_i3wm_setup
	total_custom_i3wm_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/i3wm" "$branch" 2>/dev/null)
	local total_custom_dwm_setup
	total_custom_dwm_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/dwm" "$branch" 2>/dev/null)
	local total_custom_bspwm_setup
	total_custom_bspwm_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/bspwm" "$branch" 2>/dev/null)
	local total_custom_awesome_setup
	total_custom_awesome_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/awesome" "$branch" 2>/dev/null)
	local total_custom_fluxbox_setup
	total_custom_fluxbox_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/fluxbox" "$branch" 2>/dev/null)
	local total_custom_icewm_setup
	total_custom_icewm_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/icewm" "$branch" 2>/dev/null)
	local total_custom_wmaker_setup
	total_custom_wmaker_setup=$(count_subfolders "$owner" "$repo" "$REPO_SETUP_FILES_FOLDER/wmaker" "$branch" 2>/dev/null)
	banner
	print_msg "Select Desktop Environment"
	echo " "
	echo "${Y}1. XFCE($total_custom_xfce_setup)${NC}"
	echo
	echo "${Y}2. LXQT($total_custom_lxqt_setup)${NC}"
	echo
	echo "${Y}3. OPENBOX WM($total_custom_openbox_setup)${NC}"
	echo
	echo "${Y}4. MATE (Unstable)($total_custom_mate_setup)${NC}"
	echo
	echo "${Y}5. Gnome($total_custom_gnome_setup)(WIP, so expect bugs)${NC}"
	echo
	echo "${Y}6. Cinnamon($total_custom_cinnamon_setup)${NC}"
	echo
	echo "${Y}7. I3Wm($total_custom_i3wm_setup)${NC}"
	echo
	echo "${Y}8. Dwm($total_custom_dwm_setup)${NC}"
	echo
	echo "${Y}9. Bspwm($total_custom_bspwm_setup)${NC}"
	echo
	echo "${Y}10. Awesome($total_custom_awesome_setup)${NC}"
	echo
	echo "${Y}11. Fluxbox($total_custom_fluxbox_setup)${NC}"
	echo
	echo "${Y}12. IceWM($total_custom_icewm_setup)${NC}"
	echo
	echo "${Y}13. WMaker($total_custom_wmaker_setup)${NC}"
	echo
	select_an_option 13 1 desktop_answer
	# set the variables based on chosen de
	sys_icons_folder="$TERMUX_PREFIX/share/icons"
	sys_themes_folder="$TERMUX_PREFIX/share/themes"
	# shellcheck disable=SC2154
	if [[ "$desktop_answer" == "1" ]]; then
		de_name="xfce"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="startxfce4"
	elif [[ "$desktop_answer" == "2" ]]; then
		de_name="lxqt"
		themes_folder="$sys_themes_folder"
		icons_folder="$sys_icons_folder"
		de_startup="startlxqt"
	elif [[ "$desktop_answer" == "3" ]]; then
		de_name="openbox"
		themes_folder="$sys_themes_folder"
		icons_folder="$sys_icons_folder"
		de_startup="openbox-session"
	elif [[ "$desktop_answer" == "4" ]]; then
		de_name="mate"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="mate-session"
	elif [[ "$desktop_answer" == "5" ]]; then
		de_name="gnome"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="gnome-session-minimal"
	elif [[ "$desktop_answer" == "6" ]]; then
		de_name="cinnamon"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="cinnamon-session"
	elif [[ "$desktop_answer" == "7" ]]; then
		de_name="i3wm"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="i3"
	elif [[ "$desktop_answer" == "8" ]]; then
		de_name="dwm"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="dwm"
	elif [[ "$desktop_answer" == "9" ]]; then
		de_name="bspwm"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="bspwm"
	elif [[ "$desktop_answer" == "10" ]]; then
		de_name="awesome"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="awesome"
	elif [[ "$desktop_answer" == "11" ]]; then
		de_name="fluxbox"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="fluxbox"
	elif [[ "$desktop_answer" == "12" ]]; then
		de_name="icewm"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="icewm-session"
	elif [[ "$desktop_answer" == "13" ]]; then
		de_name="wmaker"
		themes_folder="$TERMUX_HOME/.themes"
		icons_folder="$TERMUX_HOME/.icons"
		de_startup="wmaker"

	fi
	banner
	questions_theme_select
}

function questions_zsh_theme_select() {
	print_msg "${BOLD} Select zsh theme"
	echo
	echo "${Y}1. My Zsh Theme (not customizable, made for my setup) ${NC}"
	echo
	echo "${Y}2. Powerlevel10k (highly customizable) ${NC}"
	echo
	echo "${Y}3. Pure (pretty, minimal and fast zsh prompt) ${NC}"
	echo
	select_an_option 3 1 chosen_zsh_theme

	# shellcheck disable=SC2154
	if [[ "$chosen_zsh_theme" == "1" ]]; then
		selected_zsh_theme_name="td_zsh"
	elif [[ "$chosen_zsh_theme" == "2" ]]; then
		selected_zsh_theme_name="p10k_zsh"
	elif [[ "$chosen_zsh_theme" == "3" ]]; then
		selected_zsh_theme_name="pure_zsh"
	fi
}

function questions_nerd_font_select() {
	print_msg "Select nerd font you want to install...${B}"
	echo

	latest_nf_version=$(get_latest_release "ryanoasis" "nerd-fonts")

	release_json=$(curl -sSL "https://api.github.com/repos/ryanoasis/nerd-fonts/releases/tags/${latest_nf_version}")

	mapfile -t ASSET_NAMES < <(
		jq -r '
        .assets // []
        | map(select(.name | endswith(".tar.xz")))
        | .[].name
      ' <<<"$release_json"
	)

	FONT_DISPLAY=()
	for asset in "${ASSET_NAMES[@]}"; do
		FONT_DISPLAY+=("${asset%.tar.xz}")
	done

	if ((${#ASSET_NAMES[@]} == 0)); then
		print_failed "No .tar.xz fonts found for ${latest_nf_version}." >&2
		print_msg "Fallback to 0xProto..."
		sel_base_name="0xProto"
		return 1
	fi

	term_width=$(tput cols 2>/dev/null || echo 80)
	(
		for i in "${!FONT_DISPLAY[@]}"; do
			printf "%3d) %s\n" "$((i + 1))" "${FONT_DISPLAY[$i]}"
		done
	) | pr -2 -t -w"$term_width"

	echo
	select_an_option "${#ASSET_NAMES[@]}" 1 nerd_choice

	sel_base_name="${FONT_DISPLAY[$((nerd_choice - 1))]}"
}

function questions_setup_manual() {
	ask_to_chose_de
	banner
	print_msg "${BOLD}Select browser you want to install"
	echo
	echo "${Y}1. firefox${NC}"
	echo
	echo "${Y}2. chromium${NC}"
	echo
	echo "${Y}3. firefox & chromium (both)${NC}"
	echo
	echo "${Y}4. Skip${NC}"
	echo
	select_an_option 4 1 browser_answer
	# shellcheck disable=SC2154
	case "$browser_answer" in
	1) installed_browser="firefox" ;;
	2) installed_browser="chromium" ;;
	3) installed_browser="all" ;;
	4) installed_browser="skip" ;;
	esac
	banner
	print_msg "${BOLD}Select IDE you want to install"
	echo
	echo "${Y}1. VS Code${NC}"
	echo
	echo "${Y}2. Geany${NC}"
	echo
	echo "${Y}3. NeoVim${NC}"
	echo
	echo "${Y}4. All of them${NC}"
	echo
	echo "${Y}5. Skip${NC}"
	echo
	select_an_option 5 1 ide_answer
	# shellcheck disable=SC2154
	case "$ide_answer" in
	1) installed_ide="code" ;;
	2) installed_ide="geany" ;;
	3) installed_ide="neovim" ;;
	4) installed_ide="all" ;;
	5) installed_ide="skip" ;;
	esac
	echo
	if [[ "$installed_ide" == "neovim" ]] || [[ "$installed_ide" == "all" ]]; then
		print_msg "${BOLD}Select neovim config"
		echo
		echo "${Y}1. Stock${NC}"
		echo
		echo "${Y}2. NvChad${NC}"
		echo
		echo "${Y}3. LazyVim${NC}"
		echo
		echo "${Y}4. mynvim (my personal neovim config)${NC}"
		echo
		select_an_option 4 2 select_neovim_distro
		# shellcheck disable=SC2154
		case "$select_neovim_distro" in
		1) installed_nvim_distro="stock" ;;
		2) installed_nvim_distro="nvchad" ;;
		3) installed_nvim_distro="lazyvim" ;;
		4) installed_nvim_distro="mynvim" ;;
		esac
	fi
	banner
	print_msg "${BOLD}Select Media Player you want to install"
	echo
	echo "${Y}1. Vlc${NC}"
	echo
	echo "${Y}2. Mpv${NC}"
	echo
	echo "${Y}3. Both${NC}"
	echo
	echo "${Y}4. Skip${NC}"
	echo
	select_an_option 4 1 player_answer
	# shellcheck disable=SC2154
	case "$player_answer" in
	1) installed_media_player="vlc" ;;
	2) installed_media_player="mpv" ;;
	3) installed_media_player="all" ;;
	4) installed_media_player="skip" ;;
	esac
	banner
	print_msg "${BOLD}Select Photo Editor${NC}"
	echo
	echo "${Y}1. Gimp${NC}"
	echo
	echo "${Y}2. Inkscape${NC}"
	echo
	echo "${Y}3. Gimp & Inkscape (both)${NC}"
	echo
	echo "${Y}4. Skip${NC}"
	echo
	select_an_option 4 1 photo_editor_answer
	# shellcheck disable=SC2154
	case "$photo_editor_answer" in
	1) installed_photo_editor="gimp" ;;
	2) installed_photo_editor="inkscape" ;;
	3) installed_photo_editor="all" ;;
	4) installed_photo_editor="skip" ;;
	esac
	banner
	print_msg "${BOLD}Do you want to install wine in termux ${C}(without proot-distro)"
	echo
	echo "${Y}1. Native ${C}(can run only arm64 based exe)${NC}"
	echo
	echo "${Y}2. Mobox ${C}(Un-maintained) ${NC}"
	echo
	print_msg "${B}Know More About Mobox:- https://github.com/olegos2/mobox/"
	echo
	echo "${Y}3. Wine Hangover${NC}"
	echo
	echo "${Y}4. Skip${NC}"
	echo
	select_an_option 4 1 wine_answer
	# shellcheck disable=SC2154
	case "$wine_answer" in
	1) installed_wine="stock" ;;
	2) installed_wine="mobox" ;;
	3) installed_wine="wine_hangover" ;;
	4) installed_wine="skip" ;;
	esac
	banner
	confirmation_y_or_n "Do you want to Configure Hardware Acceleration" enable_hw_acc
	banner
	print_msg " By default, it only adds 4-5 wallpapers"
	echo
	print_msg "${R}This is a 1GB+ collection"
	echo
	confirmation_y_or_n "Do you want to add some more wallpapers" ext_wall_answer
	banner
	print_msg "${BOLD}Select Your shell${NC}"
	echo
	echo "${Y}1. Zsh + zinit${NC}"
	echo
	echo "${Y}2. Custom Bash prompt + ble.sh (ble.sh kind of buggy right now)${NC}"
	echo
	echo "${Y}3. Custom Bash prompt${NC}"
	echo
	select_an_option 4 1 chosen_shell_answer
	# shellcheck disable=SC2154
	case "$chosen_shell_answer" in
	1) chosen_shell_name="zsh" ;;
	2) chosen_shell_name="bash_with_ble" ;;
	3) chosen_shell_name="bash" ;;
	esac
	if [[ "$chosen_shell_name" == "zsh" ]]; then
		questions_zsh_theme_select
	fi
	banner
	echo
	print_msg "${B}Know More About Terminal Utility:- https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/$REPO_BRANCH_MAIN/docs/see-more.md#hammer_and_wrenchlearn-about-terminal-utilities"
	echo
	confirmation_y_or_n "Do you want install some terminal utility to make better terminal exprience" terminal_utility_setup_answer
	banner
	questions_nerd_font_select
	banner
	echo -e "${R}[${C}-${R}]${B} File Manager Tools Enhancement${NC}

${B}Overview:${NC}
This option enhances your file manager with powerful right-click menu features.

${B}Key Features:${NC}
   • Media Operations
     - Video processing and conversion
     - Image editing and optimization
     - Audio file management
     - PDF manipulation

   • File Management
     - Archive compression/extraction
     - File permissions control
     - Document processing
     - File encryption
     - Hash verification

   • Additional Features
     - Custom scripts integration
     - Batch processing
     - Quick actions menu

${B}How to Access:${NC}
Access these features through the 'Scripts' menu in your file manager's right-click context menu.
${NC}"
	confirmation_y_or_n "Do you want File Manager Tools tailored with powerful extra features" fm_tools
	banner
	print_msg "${BOLD} Select Gui Mode"
	echo
	echo "${Y}1. Termux:x11${NC}"
	echo
	echo "${Y}2. Both Termux:x11 and VNC${NC}"
	echo
	select_an_option 2 1 gui_mode_num

	# set gui_mode and display_number value
	# shellcheck disable=SC2154
	if [[ "$gui_mode_num" == "1" ]]; then
		gui_mode="termux_x11"
		display_number="0"
		gui_mode_name="Termux:x11"
	elif [[ "$gui_mode_num" == "2" ]]; then
		gui_mode="both"
		display_number="0"
		gui_mode_name="Both"
	fi

	banner
	confirmation_y_or_n "Do you want to start the desktop at Termux startup" de_on_startup
	if [[ "$de_on_startup" == "y" && "$gui_mode" == "both" ]]; then
		print_msg "You chose both vnc and termux:x11 to access gui mode"
		echo
		print_msg "Which will be your default"
		echo
		echo "${Y}1. Termux:x11${NC}"
		echo
		echo "${Y}2. Vnc${NC}"
		echo
		select_an_option 2 1 autostart_gui_mode_num

		# shellcheck disable=SC2154
		if [[ "$autostart_gui_mode_num" == "1" ]]; then
			default_gui_mode="termux_x11"
		elif [[ "$autostart_gui_mode_num" == "2" ]]; then
			default_gui_mode="vnc"
		fi

	fi
	banner
	echo -e "
${R}[${C}-${R}]${G}${BOLD} Linux Distro Container:- ${NC}

It will help you to install apps that aren't available in Termux.
So it will set up a Linux distro container and add options to install those apps.
Also, you can launch those installed apps from Termux like other apps.
"
	echo "Learn More:- https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/$REPO_BRANCH_MAIN/docs/proot-container.md"
	echo
	confirmation_y_or_n "Do you want to add a Linux container" distro_add_answer
}

function setup_device_gpu_model() {
	if [[ -z "$GPU_NAME" ]] || [[ "$GPU_NAME" == "unknown" ]]; then
		while true; do
			banner
			print_warn "Unable to auto detect GPU"
			echo
			print_msg "${BOLD}Please Select Your Device GPU"
			echo
			echo "${Y}1. Adreno${NC}"
			echo
			echo "${Y}2. Mali${NC}"
			echo
			echo "${Y}3. Xclipse${NC}"
			echo
			echo "${Y}4. Others (Unstable)${NC}"
			echo
			read -r -p "${Y} Enter your choise [1-4]: ${NC}" device_gpu_model

			if [[ "$device_gpu_model" =~ ^[1-4]$ ]]; then
				print_success "Continuing with answer: $device_gpu_model"
				break
			else
				print_warn "Invalid input, Please enter a number between 1 and 4"
			fi
		done

		# set gpu model name
		case "$device_gpu_model" in
		1) GPU_NAME="adreno" ;;
		2) GPU_NAME="mali" ;;
		3) GPU_NAME="xclipse" ;;
		4) GPU_NAME="others" ;;
		esac
	fi

}

# distro hardware accelrration related questions
function distro_hw_questions() {
	if [[ "$distro_add_answer" == "y" ]]; then
		case "$termux_hw_answer" in
		"virgl" | "virgl_vulkan")
			if [[ "$GPU_NAME" == "adreno" ]]; then
				banner
				print_msg "${BOLD}Select Hardware Acceleration Driver For Linux Container"
				echo "${Y}1. VirGL + ANGLE (GPU Passthrough via virpipe)${NC}"
				echo
				echo "${Y}2. Turnip (Native Adreno Vulkan Driver)${NC}"
				echo
				select_an_option 2 1 pd_hw_answer_num
				# shellcheck disable=SC2154
				case "$pd_hw_answer_num" in
				1) pd_hw_answer="virgl" ;;
				2) pd_hw_answer="turnip" ;;
				esac
				pd_hw_answer=$([ "$pd_hw_answer_num" == "1" ] && echo "virgl" || echo "turnip")
			else
				pd_hw_answer="virgl"
			fi
			;;
		"freedreno_kgsl" | "mesa_freedreno" | "mesa_zink_freedreno")
			pd_hw_answer="turnip"
			;;
		*)
			banner
			print_msg "${BOLD}Select Hardware Acceleration Driver For Linux Container"
			echo
			print_msg "If You Skip It, It Will Use The Previous Selection"
			echo
			echo "${Y}1. Mesa Zink (Vulkan-to-OpenGL Translation)${NC}"
			echo
			echo "${Y}2. VirGL (GPU Passthrough via virpipe)${NC}"
			echo
			echo "${Y}3. Turnip (Native Adreno Vulkan Driver)${NC}"
			echo
			select_an_option 3 1 pd_hw_answer_num

			case "$pd_hw_answer_num" in
			1) pd_hw_answer="zink" ;;
			2) pd_hw_answer="virgl" ;;
			3) pd_hw_answer="turnip" ;;
			esac
			;;
		esac
	fi
}

# hardware accelrration related questions
#NOTE: this get called first in hw_questions function
function exp_vulkan_support() {
	print_msg "${BOLD}First Read This"
	echo
	print_msg "${B}This:- https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/$REPO_BRANCH_MAIN/docs/hw-acceleration.md"
	echo
	print_msg "${BOLD}Select the vulkan driver"
	echo
	if [[ "${termux_arch}" == "aarch64" ]]; then
		echo "${Y}1. vulkan-wrapper-android${NC}"
		echo
		echo "${Y}2. vulkan-wrapper-android (leegao's fork)${NC}"
		echo
		echo "${Y}3. mesa-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
		echo
		echo "${Y}4. mesa-zink-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
		echo
		echo "${Y}5. mesa-vulkan-icd-freedreno (Kgsl) (adreno only)${NC}"
		echo
		echo "${Y}6. will use the old virgl way${NC}"
		echo
		select_an_option 6 1 exp_termux_vulkan_hw_answer_num

		# set gpu api name
		# shellcheck disable=SC2154
		case "$exp_termux_vulkan_hw_answer_num" in
		1) exp_termux_vulkan_hw_answer="vulkan_wrapper_android" ;;
		2) exp_termux_vulkan_hw_answer="vulkan_wrapper_android_leegaos_fork" ;;
		3) exp_termux_vulkan_hw_answer="mesa_freedreno" ;;
		4) exp_termux_vulkan_hw_answer="mesa_zink_freedreno" ;;
		5) exp_termux_vulkan_hw_answer="freedreno_kgsl" ;;
		6) exp_termux_vulkan_hw_answer="skip" ;;
		esac
	else
		echo "${Y}1. vulkan-wrapper-android${NC}"
		echo
		echo "${Y}2. mesa-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
		echo
		echo "${Y}3. mesa-zink-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
		echo
		echo "${Y}4. mesa-vulkan-icd-freedreno (Kgsl) (adreno only)${NC}"
		echo
		echo "${Y}5. will use the old virgl way${NC}"
		echo
		select_an_option 5 1 exp_termux_vulkan_hw_answer_num

		# set gpu api name
		case "$exp_termux_vulkan_hw_answer_num" in
		1) exp_termux_vulkan_hw_answer="vulkan_wrapper_android" ;;
		2) exp_termux_vulkan_hw_answer="mesa_freedreno" ;;
		3) exp_termux_vulkan_hw_answer="mesa_zink_freedreno" ;;
		4) exp_termux_vulkan_hw_answer="freedreno_kgsl" ;;
		5) exp_termux_vulkan_hw_answer="skip" ;;
		esac
	fi
}

function exp_termux_gl_hw_support() {
	banner
	echo
	print_msg "${BOLD}It will be used to enable opengl support"
	echo
	echo "${Y}1. Mesa Zink (Vulkan-to-OpenGL) + VirGL Server${NC}"
	echo
	echo "${Y}2. VirGL (GPU Passthrough via virpipe)${NC}"
	echo
	echo "${Y}3. VirGL + ANGLE OpenGL Backend${NC}"
	echo
	echo "${Y}4. VirGL + ANGLE Vulkan Backend${NC}"
	echo
	echo "${Y}5. Mesa Zink + VirGL (Vulkan-to-OpenGL via VirGL)${NC}"
	echo
	echo "${Y}6. Mesa Zink Direct (Native Vulkan-to-OpenGL)${NC}"
	echo
	echo "${Y}7. Mesa Zink Direct with Mesa-zink (Native Vulkan-to-OpenGL)${NC}"
	echo
	select_an_option 7 1 exp_termux_gl_hw_answer_num

	# set gpu api name
	# shellcheck disable=SC2154
	case "$exp_termux_gl_hw_answer_num" in
	1) exp_termux_gl_hw_answer="zink" ;;
	2) exp_termux_gl_hw_answer="virgl" ;;
	3) exp_termux_gl_hw_answer="virgl_angle" ;;
	4) exp_termux_gl_hw_answer="virgl_vulkan" ;;
	5) exp_termux_gl_hw_answer="zink_virgl" ;;
	6) exp_termux_gl_hw_answer="zink_with_mesa" ;;
	7) exp_termux_gl_hw_answer="zink_with_mesa_zink" ;;
	esac
	termux_hw_answer="${exp_termux_gl_hw_answer}"
	distro_hw_questions
}

#NOTE: it first call exp_vulkan_support then if user select vulkan_wrapper_android the it will go for exp_termux_gl_hw_answer (as name suggest it setup the opengl driver for termux) and user type 4=skip then it will go for everything using virgl option (it's kind of same as exp_termux_gl_hw_answer), then when it done for termux part it will call distro_hw_questions to setup hwa for the selected proot-distro
function hw_questions() {
	banner
	exp_vulkan_support
	# this part is for those need some hack or some other driver alongside it
	# to get the opengl access
	if [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android" ]] || [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android_leegaos_fork" ]]; then
		exp_termux_gl_hw_support
	# this part is for those can give us opengl access either through zink
	# or have a native opengl driver inside it
	elif [[ "$exp_termux_vulkan_hw_answer" == "freedreno_kgsl" ]] || [[ "$exp_termux_vulkan_hw_answer" == "mesa_freedreno" ]] || [[ "$exp_termux_vulkan_hw_answer" == "mesa_zink_freedreno" ]]; then
		termux_hw_answer="${exp_termux_vulkan_hw_answer}"
		distro_hw_questions
	# this will run if you select skip and don't want to use those
	# android-vulkan-wrapper / bionic-vulkan-wrapper / turnip / kgsl
	elif [[ "$exp_termux_vulkan_hw_answer" == "skip" ]]; then
		print_msg "${BOLD}First Read This"
		echo
		print_msg "${B}This:- https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/$REPO_BRANCH_MAIN/docs/hw-acceleration.md"
		echo
		print_msg "${BOLD}Select Hardware Acceleration API"
		echo
		echo
		print_msg "${BOLD}Select Hardware Acceleration API"
		echo
		echo "${Y}1. Mesa Zink (Vulkan-to-OpenGL) + VirGL Server${NC}"
		echo
		echo "${Y}2. VirGL (GPU Passthrough via virpipe)${NC}"
		echo
		echo "${Y}3. VirGL + ANGLE OpenGL Backend${NC}"
		echo
		echo "${Y}4. VirGL + ANGLE Vulkan Backend${NC}"
		echo
		echo "${Y}5. Mesa Zink + VirGL (Vulkan-to-OpenGL via VirGL)${NC}"
		echo
		select_an_option 5 1 termux_hw_answer_num

		# set gpu api name
		# shellcheck disable=SC2154
		case "$termux_hw_answer_num" in
		1) termux_hw_answer="zink" ;;
		2) termux_hw_answer="virgl" ;;
		3) termux_hw_answer="virgl_angle" ;;
		4) termux_hw_answer="virgl_vulkan" ;;
		5) termux_hw_answer="zink_virgl" ;;
		esac
		distro_hw_questions
	fi
}

# distro related questions
function distro_type_select() {
	print_msg "${BOLD}Select the distro type"
	echo " "
	echo "${G}chroot-distro:- ${B}https://github.com/sabamdarif/chroot-distro${NC}"
	echo " "
	echo "${G}proot-distro:- ${B}https://github.com/termux/proot-distro${NC}"
	echo " "
	echo "${Y}1. Proot Distro${NC}"
	echo " "
	echo "${Y}2. Chroot Distro${NC}"
	echo " "
	select_an_option 2 1 distro_type_answer

	# shellcheck disable=SC2154
	case "$distro_type_answer" in
	1) selected_distro_type="proot" ;;
	2) selected_distro_type="chroot" ;;
	*) selected_distro_type="proot" ;;
	esac
}

function choose_distro() {
	print_msg "${BOLD}Select Linux Distro You Want To Add"
	echo " "
	echo "${Y}1. Debian${NC}"
	echo " "
	echo "${Y}2. Ubuntu${NC}"
	echo " "
	echo "${Y}3. Arch (Unstable | isn't fully suppoted by AppStore yet)${NC}"
	echo " "
	echo "${Y}4. Fedora${NC}"
	echo " "
	select_an_option 4 1 distro_answer
	# shellcheck disable=SC2154
	case "$distro_answer" in
	1) selected_distro="debian" ;;
	2) selected_distro="ubuntu" ;;
	3) selected_distro="archlinux" ;;
	4) selected_distro="fedora" ;;
	*) selected_distro="debian" ;;
	esac

}

function setup_user_name_only() {
	echo
	print_msg "${BOLD}Create user account"
	echo
	while true; do
		echo " "
		print_msg "Default Password Will Be Set, Because Sometimes It Might Ask You For Password"
		echo
		print_msg "Password:-${C}root"
		# set password to root
		pass=root
		echo
		while true; do
			read -r -p "${R}[${C}-${R}]${G} Input username [Lowercase]: ${NC}" user_name
			if [[ -z "$user_name" ]]; then
				print_warn "You can't leave the username empty. Please enter a valid username."
			elif [[ "$user_name" =~ \  ]]; then
				print_warn "Username cannot contain spaces. Please enter a valid username."
			else
				break
			fi
		done
		echo
		local choice
		read -r -p "${R}[${C}-${R}]${Y} Do you want to continue with username ${C}$user_name ${Y}? (y/n) : ${NC}" choice
		echo
		choice="${choice:-y}"
		echo
		print_success "Continuing with answer: $choice"
		sleep 0.2
		case $choice in
		[yY]*)
			print_success "Continuing with username ${C}$user_name"
			break
			;;
		[nN]*)
			print_msg "Please provide username again."
			echo
			;;
		*)
			print_failed "Invalid input, Please enter y or n"
			;;
		esac
	done
}

function setup_user_name_and_pass() {
	echo
	print_msg "${BOLD}Create user account"
	echo
	while true; do
		while true; do
			read -r -p "${R}[${C}-${R}]${G}Input username [Lowercase]: ${NC}" user_name
			if [[ -z "$user_name" ]]; then
				print_warn "You can't leave the username empty. Please enter a valid username."
			elif [[ "$user_name" =~ \  ]]; then
				print_warn "Username cannot contain spaces. Please enter a valid username."
			else
				break
			fi
		done
		echo
		while true; do
			read -r -p "${R}[${C}-${R}]${G}Input Password (Minimum 4 characters): ${NC}" pass
			if [[ -z "$pass" ]]; then
				print_warn "You can't leave the password empty. Please enter a valid password."
			elif [[ "$user_name" =~ \  ]]; then
				print_warn "Password cannot contain spaces. Please enter a valid username."
			elif [[ ${#pass} -lt 4 ]]; then
				print_warn "Password must be at least 4 characters long. Please enter a longer password."
			else
				break
			fi
		done
		echo
		read -r -p "${R}[${C}-${R}]${Y}Do you want to continue with username ${C}$user_name ${Y}and password ${C}$pass${Y} ? (y/n) : ${NC}" choice
		echo
		choice="${choice:-y}"
		echo
		print_success "Continuing with answer: $choice"
		echo ""
		sleep 0.2
		case $choice in
		[yY]*)
			print_success "Continuing with username ${C}$user_name ${G}and password ${C}$pass"
			break
			;;
		[nN]*)
			print_msg "Please provide username and password again."
			echo
			;;
		*)
			print_failed "Invalid input, Please enter y or n"
			;;
		esac
	done
}

function distro_questions() {
	banner
	distro_type_select
	choose_distro
	banner
	confirmation_y_or_n "Do you want to configure audio support for Linux distro container" pd_audio_config_answer
	banner
	confirmation_y_or_n "Do you want to create a normal user account ${C}(Recomended)" pd_useradd_answer
	echo

	if [[ "$pd_useradd_answer" == "n" ]]; then
		print_msg "Skiping User Account Setup"
	else
		print_msg "${BOLD}Select user account type"
		echo
		echo "${Y}1. User with no password confirmation${NC}"
		echo
		echo "${Y}2. User with password confirmation${NC}"
		echo
		select_an_option 2 1 pd_pass_type
		# shellcheck disable=SC2154
		if [[ "$pd_pass_type" == "1" ]]; then
			setup_user_name_only
		elif [[ "$pd_pass_type" == "2" ]]; then
			setup_user_name_and_pass
		fi

	fi
}

# it set all the value that wil be used for printing the setup configuration (in print_conf_info)
function define_value_name() {
	# Gui mode
	if [[ "$gui_mode" == "termux_x11" ]]; then
		gui_mode_name="Termux:x11"
	elif [[ "$gui_mode" == "both" ]]; then
		gui_mode_name="Both"
	fi
	# autostart value
	if [[ "$de_on_startup" == "y" ]]; then
		autostart_value="Yes"
	elif [[ "$de_on_startup" == "n" ]]; then
		autostart_value="No"
	fi
	# browser
	if [[ "$installed_browser" == "firefox" ]]; then
		browser_name="Firefox"
	elif [[ "$installed_browser" == "chromium" ]]; then
		browser_name="Chromium"
	elif [[ "$installed_browser" == "all" ]]; then
		browser_name="Both Firefox and Chromium"
	elif [[ "$installed_browser" == "skip" ]]; then
		browser_name="Skip"
	fi
	# media player
	if [[ "$installed_media_player" == "vlc" ]]; then
		media_player_name="Vlc"
	elif [[ "$installed_media_player" == "mpv" ]]; then
		media_player_name="Mpv"
	elif [[ "$installed_media_player" == "all" ]]; then
		media_player_name="Both Vlc and Mpv"
	elif [[ "$installed_media_player" == "skip" ]]; then
		media_player_name="Skip"
	fi
	# Image Editor
	if [[ "$installed_photo_editor" == "gimp" ]]; then
		photo_editor_name="GIMP"
	elif [[ "$installed_photo_editor" == "inkscape" ]]; then
		photo_editor_name="Inkscape"
	elif [[ "$installed_photo_editor" == "all" ]]; then
		photo_editor_name="Both GIMP and Inkscape"
	elif [[ "$installed_photo_editor" == "skip" ]]; then
		photo_editor_name="Skip"
	fi
	# IDE
	if [[ "$installed_ide" == "code" ]]; then
		ide_name="VS Code (code-oss)"
	elif [[ "$installed_ide" == "geany" ]]; then
		ide_name="Geany"
	elif [[ "$installed_ide" == "neovim" ]]; then
		if [[ "$installed_nvim_distro" == "stock" ]]; then
			neovim_distro="Stock"
		elif [[ "$installed_nvim_distro" == "nvchad" ]]; then
			neovim_distro="NvChad"
		elif [[ "$installed_nvim_distro" == "lazyvim" ]]; then
			neovim_distro="LazyVim"
		elif [[ "$installed_nvim_distro" == "mynvim" ]]; then
			neovim_distro="MyNvim"
		fi
		ide_name="NeoVim ${neovim_distro}"
	elif [[ "$installed_ide" == "all" ]]; then
		ide_name="All"
	elif [[ "$installed_ide" == "skip" ]]; then
		ide_name="Skip"
	fi
	# WINE
	# shellcheck disable=SC2154
	if [[ "$installed_wine" == "stock" ]]; then
		wine_type_name="Native"
	elif [[ "$installed_wine" == "mobox" ]]; then
		wine_type_name="Mobox"
	elif [[ "$installed_wine" == "wine_hangover" ]]; then
		wine_type_name="Wine Hangover"
	elif [[ "$installed_wine" == "skip" ]]; then
		wine_type_name="Skip"
	fi
	# Extra Wallpapers
	# shellcheck disable=SC2154
	if [[ "$ext_wall_answer" == "y" ]]; then
		ext_wall_answer_confirmation="Yes"
	elif [[ "$ext_wall_answer" == "n" ]]; then
		ext_wall_answer_confirmation="No"
	fi
	# File Manager Tools
	# shellcheck disable=SC2154
	if [[ "$fm_tools" == "y" ]]; then
		fm_tools_confirmation="Yes"
	elif [[ "$fm_tools" == "n" ]]; then
		fm_tools_confirmation="No"
	fi
	# Shell
	if [[ "$chosen_shell_name" == "bash" ]]; then
		current_shell_name="Bash"
	elif [[ "$chosen_shell_name" == "bash_with_ble" ]]; then
		current_shell_name="Bash (With Ble.sh)"
	elif [[ "$chosen_shell_name" == "zsh" ]]; then
		if [[ "$selected_zsh_theme_name" == "td_zsh" ]]; then
			zsh_theme_name="My Zsh Theme"
		elif [[ "$selected_zsh_theme_name" == "p10k_zsh" ]]; then
			zsh_theme_name="Powerlevel10k"
		elif [[ "$selected_zsh_theme_name" == "pure_zsh" ]]; then
			zsh_theme_name="Pure"
		fi
		current_shell_name="Zsh ($zsh_theme_name)"
	fi
	# Terminal Utilities
	# shellcheck disable=SC2154
	if [[ "$terminal_utility_setup_answer" == "y" ]]; then
		terminal_utility_setup_confirmation="Yes"
	elif [[ "$terminal_utility_setup_answer" == "n" ]]; then
		terminal_utility_setup_confirmation="No"
	fi
	# Nerd Font
	# shellcheck disable=SC2154
	if [[ "$install_type_answer" == "1" ]]; then
		sel_font_name="$sel_base_name"
	elif [[ "$install_type_answer" == "2" ]] || [[ "$install_type_answer" == "3" ]]; then
		sel_font_name="0xProto"
	else
		sel_font_name="N/A"
	fi
	# Hardware Acceleration Status
	if [[ "$enable_hw_acc" == "y" ]]; then
		hw_acc_confirmation="Enabled"
	elif [[ "$enable_hw_acc" == "n" ]]; then
		hw_acc_confirmation="Disabled"
	fi
	# Vulkan Driver
	if [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android" ]]; then
		vulkan_driver_name="Vulkak Wrapper Android"
	elif [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android_leegaos_fork" ]]; then
		vulkan_driver_name="Vulkan Wrapper Android (leegao's fork)"
	elif [[ "$exp_termux_vulkan_hw_answer" == "mesa_freedreno" ]]; then
		vulkan_driver_name="Mesa ICD Freedreno"
	elif [[ "$exp_termux_vulkan_hw_answer" == "mesa_zink_freedreno" ]]; then
		vulkan_driver_name="Mesa Zink ICD Freedreno"
	else
		vulkan_driver_name="Might Not Support"
	fi
	# OpenGL Driver
	if [[ "$termux_hw_answer" == "zink" ]]; then
		opengl_driver_name="Zink"
	elif [[ "$termux_hw_answer" == "virgl" ]]; then
		opengl_driver_name="Virgl"
	elif [[ "$termux_hw_answer" == "virgl_angle" ]]; then
		opengl_driver_name="Virgl Angle"
	elif [[ "$termux_hw_answer" == "virgl_vulkan" ]]; then
		opengl_driver_name="VIRGL ANGLE (Vulkan)"
	elif [[ "$termux_hw_answer" == "zink_virgl" ]]; then
		opengl_driver_name="OpenGL ES (ZINK VIRGL)"
	elif [[ "$termux_hw_answer" == "zink_with_mesa" ]]; then
		opengl_driver_name="The vulkan-wrapper-android Driver With Mesa"
	elif [[ "$termux_hw_answer" == "zink_with_mesa_zink" ]]; then
		opengl_driver_name="The vulkan-wrapper-android Driver With Mesa-Zink"
	elif [[ "$termux_hw_answer" == "freedreno" ]]; then
		opengl_driver_name="Freedreno"
	else
		opengl_driver_name="Might Not Support"
	fi
	# Linux Distro Container
	if [[ "$distro_add_answer" == "y" ]]; then
		distro_container_confirmation="Enabled"
	elif [[ "$distro_add_answer" == "n" ]]; then
		distro_container_confirmation="Disabled"
	fi
	if [[ "$selected_distro_type" == "chroot" ]]; then
		distro_type=CHROOT
	elif [[ "$selected_distro_type" == "proot" ]]; then
		distro_type=PROOT
	else
		distro_type="Unable to select distro type"
	fi
	# Distro User and Pass
	if [[ "$pd_useradd_answer" == "y" ]]; then
		distro_user_name="${user_name}"
		if [[ -z "$pass" ]]; then
			distro_pass="root (password will be disabled by default)"
		else
			distro_pass="${pass}"
		fi
	elif [[ "$pd_useradd_answer" == "n" ]]; then
		distro_user_name="Null"
		distro_pass="Null"
	fi
	# Distro Audio Support
	# shellcheck disable=SC2154
	if [[ "$pd_audio_config_answer" == "y" ]]; then
		pd_audio_config_confirmation="Yes"
	elif [[ "$pd_audio_config_answer" == "n" ]]; then
		pd_audio_config_confirmation="No"
	fi
	# Distro Hardware Acceleration
	if [[ "$enable_hw_acc" == "y" ]]; then
		distro_hw_acc_confirmation="Enabled"
	elif [[ "$enable_hw_acc" == "n" ]]; then
		distro_hw_acc_confirmation="Disabled"
	fi
	# Distro Vulkan Driver
	if [[ "$pd_hw_answer" == "zink" ]]; then
		distro_vulkan_driver="Not Supported"
	elif [[ "$pd_hw_answer" == "virgl" ]]; then
		distro_vulkan_driver="Not Supported"
	elif [[ "$pd_hw_answer" == "turnip" ]]; then
		distro_vulkan_driver="Turnip"
	elif [[ "$pd_hw_answer" == "freedreno" ]]; then
		distro_vulkan_driver="Freedreno"
	else
		distro_vulkan_driver="Unable to select"
	fi
	# Distro OpenGL Driver
	if [[ "$pd_hw_answer" == "zink" ]]; then
		distro_opengl_driver="Zink"
	elif [[ "$pd_hw_answer" == "virgl" ]]; then
		distro_opengl_driver="Virgl"
	elif [[ "$pd_hw_answer" == "virgl" ]]; then
		distro_opengl_driver="Virgl"
	elif [[ "$pd_hw_answer" == "turnip" ]]; then
		distro_opengl_driver="Turnip"
	elif [[ "$pd_hw_answer" == "freedreno" ]]; then
		distro_opengl_driver="Freedreno"
	else
		distro_opengl_driver="Unable to select"
	fi
	# Distro Terminal Utilities
	if [[ "$terminal_utility_setup_answer" == "y" ]]; then
		distro_terminal_utility_setup_confirmation="Yes"
	elif [[ "$terminal_utility_setup_answer" == "n" ]]; then
		distro_terminal_utility_setup_confirmation="No"
	fi
}

function print_conf_info() {
	define_value_name
	trap '' SIGINT SIGTSTP
	banner
	print_msg "Installation Configuration Summary"
	echo
	echo "${G}Desktop Environment${NC}"
	echo "   • Desktop: $(echo "$de_name" | tr '[:lower:]' '[:upper:]')"
	echo "   • Desktop Style: ${style_answer}) ${style_name}"
	echo "   • GUI Access: ${gui_mode_name}"
	echo "   • Auto-start: ${autostart_value}"
	sleep 0.015

	echo "${G}Applications${NC}"
	echo "   • Browser: ${browser_name}"
	echo "   • Media Player: ${media_player_name}"
	echo "   • Image Editor: ${photo_editor_name}"
	echo "   • IDE: ${ide_name}"
	echo "   • WINE: ${wine_type_name}"
	sleep 0.015

	echo "${G}Customization${NC}"
	echo "   • Extra Wallpapers: ${ext_wall_answer_confirmation}"
	echo "   • File Manager Tools: ${fm_tools_confirmation}"
	sleep 0.015

	echo "${G}Terminal Setup${NC}"
	echo "   • Shell: ${current_shell_name}"
	echo "   • Terminal Utilities: ${terminal_utility_setup_confirmation}"
	echo "   • Font: ${sel_font_name}"
	sleep 0.015

	echo "${G}Hardware Acceleration${NC}"
	echo "   • Status: ${hw_acc_confirmation}"
	if [[ "$enable_hw_acc" == "y" ]]; then
		echo "   • GPU: $(echo "$GPU_NAME" | tr '[:lower:]' '[:upper:]')"
		echo "   • Vulkan Driver: ${vulkan_driver_name}"
		echo "   • OpenGL Driver: ${opengl_driver_name}"
	fi
	sleep 0.015

	echo "${G}Linux Distro Container${NC}"
	echo "   • Distro Status: ${distro_container_confirmation}"
	if [[ "$distro_add_answer" == "y" ]]; then
		echo "   • Distro Type: ${distro_type}"
		echo "   • Distribution: ${selected_distro}"
		echo "   • Distro Username: ${distro_user_name}"
		echo "   • Distro Pass: ${distro_pass}"
		echo "   • Audio Support: ${pd_audio_config_confirmation}"
	fi
	if [[ "$enable_hw_acc" == "y" ]]; then
		echo "   • Hardware Acceleration: ${distro_hw_acc_confirmation}"
		echo "   • Vulkan Driver: ${distro_vulkan_driver}"
		echo "   • OpenGL Driver: ${distro_opengl_driver}"
	fi
	echo "   • Terminal Utilities: ${distro_terminal_utility_setup_confirmation}"
	sleep 0.015
	# Re-enable keyboard interruptions
	trap - SIGINT SIGTSTP
	wait_for_keypress
}

#########################################################################
#
# Select Install Type and load config
#
#########################################################################

function questions_install_type() {
	banner
	# Clear screen and show title first
	print_msg "A Quick Overview"
	echo
	sleep 0.2

	echo -e "${R}[${C}-${R}]${G} Key Terms:${NC}
• Generic: Pre-configured options that so far work best in most of the devices\n
• Recommended: Tested configurations with minimal known issues\n
• Hardware Acceleration: Uses your device's GPU for better graphics render\n
• Custom: Full control over all installation options\n
"
	echo "${R}[${Y}!${R}]${R} Important Note: ${NC}"
	echo -e "${B}
Generic is only recomended for beginners\n
For most users who are familiar with Termux, the custom option is recommended, as most features are only available in the custom option
${NC}"

	# Show selection options
	print_msg "Select Install Type"
	echo " "
	echo "${Y}1. Custom${NC}"
	echo " "
	echo "${Y}2. Generic (with hardware acceleration)${NC}"
	echo " "
	echo "${Y}3. Generic (without hardware acceleration)${NC}"
	echo " "

	select_an_option 3 1 install_type_answer
	if [[ "$install_type_answer" == "1" ]]; then
		questions_setup_manual
	elif [[ "$install_type_answer" == "2" ]]; then

		######################################################################
		# ********* Generic Recomended With Hardware Acceleration ********** #
		######################################################################
		ask_to_chose_de
		setup_device_gpu_model
		# download configuration
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/generic.conf"
		# shellcheck disable=SC1091
		source generic.conf
		check_and_delete "generic.conf"
		local device_brand_name
		device_brand_name=$(getprop ro.product.brand | cut -d ' ' -f 1)
		if [[ "$GPU_NAME" == "adreno" ]]; then
			download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/hwa/adreno/generic-adreno.conf"
			# shellcheck disable=SC1091
			source generic-adreno.conf
			check_and_delete "generic-adreno.conf"
		elif [[ "$GPU_NAME" == "mali" ]]; then
			if [[ $device_brand_name == samsung* ]]; then
				download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/hwa/mali/samsung/generic-samsung-mali.conf"
				# shellcheck disable=SC1091
				source generic-samsung-mali.conf
				check_and_delete "generic-samsung-mali.conf"
			else
				download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/hwa/mali/generic-mali.conf"
				# shellcheck disable=SC1091
				source generic-mali.conf
				check_and_delete "generic-mali.conf"
			fi
		else
			download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/hwa/generic-others.conf"
			# shellcheck disable=SC1091
			source generic-others.conf
			check_and_delete "generic-others.conf"
		fi
		# setup extra config if it's lite mode install
		if [[ "$LITE_MODE" == "1" || "$LITE_MODE" == "true" ]]; then
			download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/generic-lite.conf"
			# shellcheck disable=SC1091
			source generic-lite.conf
			check_and_delete "generic-lite.conf"
		fi

		# create username for distro
		banner
		setup_user_name_only
	elif [[ "$install_type_answer" == "3" ]]; then

		######################################################################
		# ******* Generic Recomended Without Hardware Acceleration ********* #
		######################################################################
		ask_to_chose_de
		# download configuration
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/generic.conf"
		# shellcheck disable=SC1091
		source generic.conf
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/nohwa/generic-nohwa.conf"
		# shellcheck disable=SC1091
		source generic-nohwa.conf
		check_and_delete "generic-nohwa.conf"
		# setup extra config if it's lite mode install
		if [[ "$LITE_MODE" == "1" || "$LITE_MODE" == "true" ]]; then
			download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/configuration/generic/generic-lite.conf"
			# shellcheck disable=SC1091
			source generic-lite.conf
			check_and_delete "generic-lite.conf"
		fi

		# create username for distro
		banner
		setup_user_name_only
	fi
}

function load_local_config() {
	banner
	local config_path="$1"

	# Check if the file exists
	if [[ ! -f "$config_path" ]]; then
		print_failed "$config_path does not exist."
		exit 1
	fi

	# Check if the file has a .conf extension
	if [[ "$config_path" != *.conf ]]; then
		print_failed "$config_path does not have a .conf extension."
		exit 1
	fi

	# Check if the file is not empty (not 0KB)
	if [[ ! -s "$config_path" ]]; then
		print_failed "$config_path is empty."
		exit 1
	fi
	print_success "Using the local configuration file..."
	# shellcheck disable=SC1090
	source "$config_path"
	sleep 3
	validate_required_vars
}

#########################################################################
#
# Update System, Install Required Packages Repo, Requirements checkup
#
#########################################################################

function chose_mirror() {
	print_msg "${BOLD}Selecting best termux packages mirror please wait"
	# unlink "$TERMUX_PREFIX/etc/termux/chosen_mirrors" &>/dev/null
	# ln -s "$TERMUX_PREFIX/etc/termux/mirrors/all" "$TERMUX_PREFIX/etc/termux/chosen_mirrors" &>/dev/null
	# pkg --check-mirror update
	if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termux-fastest-repo"
		chmod +x termux-fastest-repo
		# shellcheck disable=SC1091
		. termux-fastest-repo
		check_and_delete "termux-fastest-repo"
	fi
}

function update_sys() {
	banner
	if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
		print_msg "${BOLD}Updating System...."
		pacman -Syu --noconfirm
	else
		print_msg "Do you want to run a speed test to find the fastest repo for you?"
		echo "The speed test will check all mirrors in all"
		echo "mirror groups, or only the group you selected."
		echo "This process may take some time."
		confirmation_y_or_n "Do you want to continue" confirmation_speedtest
		# shellcheck disable=SC2154
		if [[ "$confirmation_speedtest" == "y" ]]; then
			chose_mirror
		fi
		print_msg "${BOLD}Updating System...."
		apt update -y -o Dpkg::Options::="--force-confnew"
		apt upgrade -y -o Dpkg::Options::="--force-confnew"
	fi
}

function get_termux_arch() {
	APP_ARCH=$(uname -m)
	SUPPORTED_ARCH="$(getprop ro.product.cpu.abilist)"
	case "$APP_ARCH" in
	aarch64) termux_arch="aarch64" ;;
	armv7* | arm | armv8*) termux_arch="arm" ;;
	esac
}

function try_to_autodetect_gpu() {
	local gpu_egl
	local gpu_vulkan
	gpu_egl=$(getprop ro.hardware.egl)
	gpu_vulkan=$(getprop ro.hardware.vulkan)
	detected_gpu="$(echo -e "$gpu_egl\n$gpu_vulkan" | sort -u | tr '\n' ' ' | sed 's/ $//')"
	if echo "$detected_gpu" | grep -iq "adreno"; then
		GPU_NAME="adreno"
	elif echo "$detected_gpu" | grep -iqE "mali|meow"; then
		GPU_NAME="mali"
	elif echo "$detected_gpu" | grep -iqE "xclipse|samsung"; then
		GPU_NAME="xclipse"
	else
		GPU_NAME="unknown"
	fi
}

function check_system_requirements() {
	while true; do
		local errors=0
		clear

		# Disable keyboard interruptions
		trap '' SIGINT SIGTSTP

		printf "%s############################################################\n" "$C"
		printf "%s#                                                          #\n" "$C"
		printf "%s#  ▀█▀ █▀▀ █▀█ █▀▄▀█ █ █ ▀▄▀   █▀▄ █▀▀ █▀ █▄▀ ▀█▀ █▀█ █▀█  #\n" "$C"
		printf "%s#   █  ██▄ █▀▄ █   █ █▄█ █ █   █▄▀ ██▄ ▄█ █ █  █  █▄█ █▀▀  #\n" "$C"
		printf "%s#                                                          #\n" "$C"
		printf "%s################# System Compatibility Check ###############%s\n" "$C" "$NC"
		echo " "
		sleep 0.3
		# Check if running on Android
		ANDROID_VERSION=$(getprop ro.build.version.release | cut -d'.' -f1)

		if [[ "$(uname -o)" == "Android" ]]; then
			if [[ "$ANDROID_VERSION" -ge 8 ]]; then
				print_success "Running on: ${NC}Android $ANDROID_VERSION"
			else
				print_failed "Running on: ${NC}Android $ANDROID_VERSION is not recomended"
				((errors++))
			fi
		else
			print_failed "Not running on Android"
			((errors++))
		fi
		sleep 0.2
		# Android device soc & model details
		MODEL="$(getprop ro.product.brand) $(getprop ro.product.model)"
		print_success "Device: ${NC}$MODEL"
		sleep 0.2
		PROCESSOR_BRAND_NAME="$(getprop ro.soc.manufacturer)"
		PROCESSOR_NAME="$(getprop ro.soc.model)"
		HARDWARE="$(getprop ro.hardware)"
		if [[ -n "$PROCESSOR_BRAND_NAME" && -n "$PROCESSOR_NAME" ]]; then
			print_success "SOC: ${NC}$PROCESSOR_BRAND_NAME $PROCESSOR_NAME"
		else
			print_success "SOC: ${NC}$HARDWARE"
		fi
		sleep 0.2
		# Check GPU
		try_to_autodetect_gpu
		if [[ "$GPU_NAME" == "adreno" ]] || [[ "$GPU_NAME" == "mali" ]] || [[ "$GPU_NAME" == "xclipse" ]]; then
			print_success "GPU: ${NC}$GPU_NAME"
		else
			print_warn "Unknown GPU: ${NC}$GPU_NAME"
		fi
		sleep 0.2
		# Check architecture
		if [[ "$termux_arch" == "aarch64" ]] || [[ "$termux_arch" == "arm" ]]; then
			print_success "App architecture: ${NC}$APP_ARCH"
		else
			print_failed "Unsupported architecture: $APP_ARCH, requires aarch64/arm/armv7*/armv8*"
			((errors++))
		fi
		sleep 0.2
		# Check for termux app requirements
		if [[ -d "$TERMUX_PREFIX" ]]; then
			print_success "Termux PREFIX: ${NC}Directory found"
			sleep 0.2
			local latest_termux_app_tag
			latest_termux_app_tag=$(get_latest_release "termux" "termux-app")
			if [[ "$TERMUX_VERSION" == "${latest_termux_app_tag#v}" ]]; then
				print_success "Termux Version: ${NC}$TERMUX_VERSION"
				sleep 0.2
				local termux_build
				termux_build=$(echo "$TERMUX_APK_RELEASE" | awk '{print tolower($0)}')
				if [[ "$termux_build" == "github" ]] || [[ "$termux_build" == "fdroid" ]]; then
					print_success "Termux Build: ${NC}$TERMUX_APK_RELEASE"
					sleep 0.2
				else
					print_failed "$TERMUX_APK_RELEASE build is not recomended"
					echo "${NC} Update Termux:- https://github.com/termux/termux-app/releases ${NC}"
					sleep 0.2
				fi
			else
				print_warn "Termux Version: ${NC}$TERMUX_VERSION (Not Recomended)"
				if [[ $(getprop ro.product.cpu.abi) == "arm64-v8a" ]]; then
					echo "${R}[${G}!${R}]${G} Update Termux:- https://github.com/termux/termux-app/releases/download/${latest_termux_app_tag}/termux-app_${latest_termux_app_tag}+github-debug_arm64-v8a.apk${NC}"
				elif [[ $(getprop ro.product.cpu.abi) == "armeabi-v7a" ]]; then
					echo "${R}[${G}!${R}]${G} Update Termux:- https://github.com/termux/termux-app/releases/download/${latest_termux_app_tag}/termux-app_${latest_termux_app_tag}+github-debug_armeabi-v7a.apk${NC}"
				else
					echo "${R}[${G}!${R}]${G} Update Termux:- https://github.com/termux/termux-app/releases/download/${latest_termux_app_tag}/termux-app_${latest_termux_app_tag}+github-debug_universal.apk${NC}"
				fi
				sleep 0.2
			fi
		else
			print_failed "Termux PREFIX: directory not found"
			((errors++))
			sleep 0.2
		fi
		# Check available storage space
		FREE_SPACE=$(df -h "$TERMUX_HOME" | awk 'NR==2 {print $4}')
		if [[ $(df "$TERMUX_HOME" | awk 'NR==2 {print $4}') -gt 4194304 ]]; then
			print_success "Available storage: ${NC}$FREE_SPACE"
		else
			print_warn "Low storage space: ${NC}$FREE_SPACE (4GB recommended)"
		fi
		sleep 0.2
		# Check RAM
		TOTAL_RAM=$(free -htm | awk '/Mem:/ {print $2}')
		if [[ $(free -m | awk 'NR==2 {print $2}') -gt 2048 ]]; then
			print_success "RAM: ${NC}${TOTAL_RAM}"
		else
			print_warn "Low RAM: ${NC}${TOTAL_RAM} (2GB recommended)"
		fi
		sleep 0.2
		# Check termux x11
		if cmd package list packages --user 0 -e -f | sed 's/package://; s/\.apk=/\.apk /' | grep -q "com.termux.x11"; then
			print_success "Termux-x11: ${NC}Installed"
		else
			if pm list packages -e | sed 's/package://' | grep -q "termux.x11"; then
				print_success "Termux-x11: ${NC}Installed"
			else
				local latest_termux_x11_tag
				latest_termux_x11_tag=$(get_latest_release "termux" "termux-x11")
				print_failed "Termux-x11: ${NC}Not Installed"
				if [[ $(getprop ro.product.cpu.abi) == "arm64-v8a" ]]; then
					print_msg "Install Termux-x11:- ${NC}https://github.com/termux/termux-x11/releases/download/${latest_termux_x11_tag}/app-arm64-v8a-debug.apk"
				elif [[ $(getprop ro.product.cpu.abi) == "armeabi-v7a" ]]; then
					print_msg "Install Termux-x11:- ${NC}https://github.com/termux/termux-x11/releases/download/${latest_termux_x11_tag}/app-armeabi-v7a-debug.apk"
				else
					print_msg "Install Termux-x11:- ${NC}https://github.com/termux/termux-x11/releases/download/${latest_termux_x11_tag}/app-universal-debug.apk"
				fi
				((errors++))
			fi
		fi
		# Check termux API
		if cmd package list packages --user 0 -e -f | sed 's/package://; s/\.apk=/\.apk /' | grep -q "com.termux.api"; then
			IS_TERMUX_API_INSTALLED=true
			print_success "Termux-API: ${NC}Installed"
		else
			# Fallback check using pm
			if pm list packages -e | sed 's/package://' | grep -q "termux.api"; then
				IS_TERMUX_API_INSTALLED=true
				print_success "Termux-API: ${NC}Installed"
			else
				local latest_termux_api_tag
				latest_termux_api_tag=$(get_latest_release "termux" "termux-api")
				print_failed "Termux-API: ${NC}Not Installed"
				print_msg "Install Termux-API:- ${NC}https://github.com/termux/termux-api/releases/download/${latest_termux_api_tag}/termux-api-app_${latest_termux_api_tag}+github-debug.apk"
				((errors++))
			fi
		fi
		echo " "
		if [[ $errors -eq 0 ]]; then
			print_success "All system requirements met!"
			sleep 0.2
			return 0
		else
			while true; do
				print_failed "Found $errors error(s). System requirements not met."
				sleep 0.2
				print_msg "Type 'a' to check again"
				read -r -p "${R}[${C}-${R}]${Y} Do you want to continue anyway (Not Recomended) ${Y}(y/n/a) ${NC}" sys_requirements_check
				case $sys_requirements_check in
				[yY]*)
					echo
					print_success "Continuing aniway..."
					echo
					sleep 0.2
					break 2
					;;
				[aA]*)
					echo
					print_success "Starting check again..."
					echo
					sleep 0.2
					break
					;;
				[nN]*)
					trap - SIGINT SIGTSTP
					exit 1
					;;
				*)
					echo
					print_failed "Invalid input. Please enter 'y' / 'n' / 'a'."
					echo
					;;
				esac
			done
			log_debug "System requirements not met $sys_requirements_check"
		fi
	done
}

function print_recomended_msg() {
	check_system_requirements
	echo
	print_msg "${BOLD}Pre-Installation Requirements"
	echo
	echo "${G}Essential Steps:${NC}"
	echo "   • Start with a clean installation"
	echo "   • Ensure at least 1GB of available data"
	echo "   • Use a stable internet connection or VPN"
	echo
	echo "${G}Device Settings:${NC}"
	echo "   • Enable 'Keep screen on' in Termux settings"
	if [[ "$ANDROID_VERSION" -ge 12 ]]; then
		echo "   • Disable Phantom Process Killer (Android 12+ requirement)"
	fi
	echo
	echo "${G}Important Notes:${NC}"
	echo "   • Keep Termux open during the entire installation"
	echo "   • Review all README documentation carefully"
	echo "   • In the multi selection option press enter to go with the default option"
	echo
	# Re-enable keyboard interruptions
	trap - SIGINT SIGTSTP
	wait_for_keypress
}

function install_required_packages() {
	banner
	print_msg "${BOLD}Installing required packages..."
	echo

	if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
		package_install_and_check "wget git jq curl tar xz-utils gzip libpopt termux-am termux-api"
	else
		package_install_and_check "wget git jq curl tar xz-utils gzip libpopt termux-am x11-repo tur-repo termux-api"
	fi
}

function recheck_basic_packages() {
	banner
	print_msg "${BOLD}Checking required packages..."
	local max_retries=3
	local retry_count=0
	local basic_packages=("wget" "git" "jq" "curl" "tar" "gzip" "termux-am" "termux-api-start")
	local pack

	while [[ "$retry_count" -le "$max_retries" ]]; do
		local missing_packages=()
		for pack in "${basic_packages[@]}"; do
			print_msg "Checking command:- $pack"
			if ! command -v "$pack" >/dev/null 2>&1; then
				missing_packages+=("$pack")
			else
				print_success "$pack command exists"
			fi
		done

		[[ ${#missing_packages[@]} -eq 0 ]] && return 0

		((retry_count++))
		print_msg "Attempt $retry_count: Installing missing packages..."
		print_msg "Missing packages: ${missing_packages[*]}"
		install_required_packages
	done

	print_failed "Error: Failed to install packages after 3 attempts"
	print_failed "Missing packages: ${missing_packages[*]}"
	exit 1
}

function install_desktop() {
	log_debug "Starting desktop installation" "Desktop: $de_name"
	banner
	if [[ "$de_name" == "xfce" ]]; then
		print_msg "${BOLD}Installing Xfce4 Desktop"
		package_install_and_check "xfce4 xfce4-goodies xfce4-pulseaudio-plugin xfce4-battery-plugin xfce4-docklike-plugin xfce4-notifyd-static xfce4-cpugraph-plugin kvantum"
	elif [[ "$de_name" == "lxqt" ]]; then
		print_msg "${BOLD}Installing Lxqt Desktop"
		echo
		package_install_and_check "lxqt openbox gtk3 papirus-icon-theme xorg-xsetroot kvantum"
	elif [[ "$de_name" == "openbox" ]]; then
		print_msg "${BOLD}Installing Openbox WM"
		echo
		package_install_and_check "openbox polybar xorg-xsetroot xorg-xprop lxappearance wmctrl feh firefox rofi bmon xcompmgr gtk3 gedit xmllint kvantum"
	elif [[ "$de_name" == "mate" ]]; then
		print_msg "${BOLD}Installing MATE"
		echo
		package_install_and_check "mate*"
		package_install_and_check "marco mousepad xfce4-taskmanager eog kvantum"
	elif [[ "$de_name" == "i3wm" ]]; then
		print_msg "${BOLD}Installing i3WM"
		package_install_and_check "i3 rofi mpv polybar xcompmgr nitrogen"
	elif [[ "$de_name" == "dwm" ]]; then
		print_msg "${BOLD}Installing DWM"
		package_install_and_check "dwm"
	elif [[ "$de_name" == "bspwm" ]]; then
		print_msg "${BOLD}Installing BSPWM"
		package_install_and_check "bspwm lxappearance xorg-xsetroot rofi feh st nemo"
	elif [[ "$de_name" == "wmaker" ]]; then
		print_msg "${BOLD}Installing WMAKER"
		package_install_and_check "wmaker lxappearance xterm nemo"
	elif [[ "$de_name" == "awesome" ]]; then
		print_msg "${BOLD}Installing AWESOME WM"
		package_install_and_check "awesome"
	elif [[ "$de_name" == "fluxbox" ]]; then
		print_msg "${BOLD}Installing Fluxbox WM"
		echo
		package_install_and_check "fluxbox xorg-xsetroot xorg-xprop lxappearance wmctrl feh firefox rofi bmon xcompmgr gtk3 gedit xmllint"
	elif [[ "$de_name" == "icewm" ]]; then
		print_msg "${BOLD}Installing Ice WM"
		echo
		package_install_and_check "icewm"
		package_install_and_check "xdg-menu"
	elif [[ "$de_name" == "gnome" ]]; then
		print_msg "${BOLD}Installing Gnome"
		echo
		mkdir gnome_packages_files
		cd gnome_packages_files || exit 1
		if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
			download_and_extract "https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/gnome-shell/debs-${termux_arch}.zip"
			download_file "https://github.com/$REPO_OWNER/Termux-AppStore/releases/download/files/refine_0.5.10_${termux_arch}.deb"
			dpkg --configure -a
			apt --fix-broken install -y
			apt install ./*deb -y
			apt install --fix-missing -y
		elif [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
			download_and_extract "https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/gnome-shell/pkgs-${termux_arch}.zip"
			download_file "https://github.com/$REPO_OWNER/Termux-AppStore/releases/download/files/refine_0.5.10_${termux_arch}.pkg.tar.xz"
			pacman -U --noconfirm ./*.pkg.tar.xz
		else
			print_failed "Unsupported package manger, you need APT / PACMAN"
			exit 1
		fi
		cd ..
		check_and_delete "gnome_packages_files"
		package_install_and_check "xfce4-terminal eog"
	elif [[ "$de_name" == "cinnamon" ]]; then
		print_msg "${BOLD}Installing Cinnamon"
		echo
		package_install_and_check "cinnamon nemo gnome-terminal gnome-screenshot eog"
	fi
	if [[ "$LITE_MODE" != "1" && "$LITE_MODE" != "true" ]]; then
		package_install_and_check "file-roller pavucontrol gnome-font-viewer evince galculator xorg-xrdb"
	fi
	# Uncomment if additional package installation is needed
	# if [[ "$distro_add_answer" == "y" ]]; then
	#     package_install_and_check "xdg-utils"
	# fi
	print_to_config "de_startup"
	print_to_config "de_name"
	print_to_config "themes_folder"
	print_to_config "icons_folder"
	log_debug "Desktop installation process done"
}

function ext_setup_for_stock() {
	if [[ "$de_name" == "icewm" ]]; then
		print_msg "Genarating a simple menu for icewm..."
		check_and_backup "$TERMUX_HOME/.icewm"
		check_and_create_directory "$TERMUX_HOME/.icewm"
		xdg_menu --format icewm --fullmenu --root-menu "$TERMUX_PREFIX/etc/xdg/menus/termux-applications.menu" >~/.icewm/programs
	fi
}

#########################################################################
#
# Theme Installer
#
#########################################################################
function set_config_dir() {
	if [[ "$de_name" == "xfce" ]]; then
		config_dirs=(autostart cairo-dock eww picom dconf gtk-3.0 Mousepad pulse Thunar menu ristretto rofi xfce4)
	elif [[ "$de_name" == "lxqt" ]]; then
		config_dirs=(fontconfig gtk-3.0 lxqt pcmanfm-qt QtProject.conf glib-2.0 Kvantum openbox qterminal.org)
	elif [[ "$de_name" == "mate" ]]; then
		config_dirs=(caja dconf galculator gtk-3.0 Kvantum lximage-qt menus Mousepad pavucontrol.ini xfce4)
	else
		config_dirs=(dconf gedit Kvantum openbox pulse rofi xfce4 enchant gtk-3.0 mimeapps.list polybar QtProject.conf Thunar)
	fi
}

function ext_wall_setup() {
	banner
	if [[ "$ext_wall_answer" == "n" ]]; then
		print_msg "${C}Skipping Extra Wallpapers Setup..."
		echo
	elif [[ "$ext_wall_answer" == "y" ]]; then
		# if we doesn't set this to only run when CALL_FROM_CHANGE_STYLE == false then it will clone the wallpapers each time user run --change style
		if [[ "$CALL_FROM_CHANGE_STYLE" == false ]]; then
			print_msg "${BOLD}Installing Some Extra Wallpapers..."
			echo
			check_and_create_directory "$TERMUX_PREFIX/share/backgrounds"
			# download_and_extract "https://archive.org/download/wallpaper-extra.tar/wallpaper-extra.tar.gz" "$TERMUX_PREFIX/share/backgrounds/"
			cd "$TERMUX_HOME" || exit 1
			git clone --recursive --depth=1 -j "$(nproc)" https://github.com/$REPO_OWNER/wallpapers.git wallpapers-collection
			cd wallpapers-collection || exit 1
			check_and_delete ".git"
			mv ./* "$TERMUX_PREFIX/share/backgrounds/"
			cd "$TERMUX_HOME" || exit 1
			check_and_delete "wallpapers-collection"
		fi
	fi
	print_to_config "ext_wall_answer"
}

function theme_installer() {
	log_debug "Starting theme installation" "Theme: $style_name"
	banner
	print_msg "${BOLD}Configuring Theme: ${C}${style_name}"
	echo
	package_install_and_check "gnome-themes-extra gtk2-engines-murrine"
	sleep 3
	banner
	print_msg "${BOLD}Configuring Wallpapers..."
	echo
	check_and_create_directory "$TERMUX_PREFIX/share/backgrounds"
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/wallpaper.tar.gz" "$TERMUX_PREFIX/share/backgrounds/"
	banner
	print_msg "${BOLD}Configuring Icon Pack..."
	echo
	package_install_and_check "gdk-pixbuf"
	if [[ -z "$icons_folder" ]]; then
		icons_folder="$TERMUX_HOME/.icons"
	fi
	check_and_create_directory "$icons_folder"
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/icon.tar.gz" "$icons_folder"

	if [[ "$de_name" == "xfce" ]]; then
		local icons_themes_names
		icons_themes_names=$(ls "$icons_folder")
		local icons_theme
		for icons_theme in $icons_themes_names; do
			if [[ -d "$icons_folder/$icons_theme" ]]; then
				print_msg "Creating icon cache..."
				gtk-update-icon-cache -f -t "$icons_folder/$icons_theme"
			fi
		done
	fi

	local sys_icons_themes_names
	sys_icons_themes_names=$(ls "$TERMUX_PREFIX/share/icons")
	local sys_icons_theme
	for sys_icons_theme in $sys_icons_themes_names; do
		if [[ -d "$sys_icons_folder/$sys_icons_theme" ]]; then
			print_msg "Creating icon cache..."
			gtk-update-icon-cache -f -t "$sys_icons_folder/$sys_icons_theme"
		fi
	done

	print_msg "${BOLD}Installing Theme..."
	echo
	if [[ -z "$themes_folder" ]]; then
		themes_folder="$TERMUX_HOME/.themes"
	fi
	check_and_create_directory "$themes_folder"
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/theme.tar.gz" "$themes_folder"

	if [[ -d "$TERMUX_HOME/.config" ]] || [[ -d "$TERMUX_HOME/.local" ]]; then
		print_msg "Creating backup of old config..."
		must_back_folders=("$TERMUX_HOME/.config")
		if [[ -d "$TERMUX_HOME/.local" ]]; then
			must_back_folders+=("$TERMUX_HOME/.local")
		fi
		tar -cJvf "$TERMUX_HOME/old-config-$(date +%Y%m%d-%H%M%S).tar.xz" --warning=no-file-removed "${must_back_folders[@]}"
	fi

	print_msg "Applying Custom Configuration..."
	echo
	check_and_create_directory "$TERMUX_HOME/.config"
	set_config_dir

	for the_config_dir in "${config_dirs[@]}"; do
		check_and_delete "$TERMUX_HOME/.config/$the_config_dir"
	done

	if [[ "$de_name" == "openbox" ]]; then
		download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/config.tar.gz" "$TERMUX_HOME"
	else
		download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/config.tar.gz" "$TERMUX_HOME/.config/"
	fi
}

#########################################################################
#
# Install Additional Packages For Setup
#
#########################################################################

function additional_required_steps() {
	banner
	if [[ "$de_name" == "xfce" ]]; then
		print_msg "${BOLD} Installing Additional Packages If Required...${NC}"
		echo
		if [[ "$style_answer" == "4" ]] || [[ "$style_answer" == "5" ]]; then
			install_font_for_style "${style_answer}"
		fi

		if [[ "$style_answer" == "5" ]] || [[ "$style_answer" == "6" ]]; then
			package_install_and_check "eww"
		fi

		if [[ "$style_answer" == "6" ]]; then
			package_install_and_check "rofi"
		fi

		if [[ "$style_answer" == "3" ]]; then
			package_install_and_check "xdotool"
		fi

	elif [[ "$de_name" == "openbox" ]]; then
		if [[ "$style_answer" == "1" ]]; then
			package_install_and_check "xfce4-settings mpd thunar"
			install_font_for_style "1"
		elif [[ "$style_answer" == "2" ]]; then
			package_install_and_check "devilspie2 xfce4-terminal thunar dunst python python3 tint2 xdotool"
			install_font_for_style "2"
			print_msg "${BOLD}Installing package: ${C}pywal"
			pip install pywal
			print_msg "${BOLD}Installing package: ${C}pyyaml"
			pip install pyyaml
			print_msg "${BOLD}Installing package: ${C}pyxdg"
			pip install pyxdg
			print_msg "${BOLD}Installing package: ${C}docopt"
			pip install docopt
			print_msg "${BOLD}Installing package: ${C}rofimoji"
			pip install rofimoji
		fi
	elif [[ "$de_name" == "i3wm" ]]; then
		if [[ "$style_answer" == "1" ]]; then
			install_font_for_style "1"
		fi

	fi
}

#########################################################################
#
# Setup Selected Style And Wallpapers / setup config
#
#########################################################################

function setup_config() {
	cd "$TERMUX_HOME" || return
	if [[ ${style_answer} =~ ^[1-9][0-9]*$ ]]; then
		banner
		print_msg "${BOLD}Installing $de_name Style: ${C}${style_answer}"
		theme_installer
		additional_required_steps
		print_to_config "style_answer"
	else
		print_failed "Failed to select style..."
	fi
}

#########################################################################
#
# Setup required permissions
#
#########################################################################

function setup_folder() {
	banner
	print_msg "${BOLD}Configuring Storage..."
	echo
	while true; do
		termux-setup-storage
		sleep 4
		if [[ -d ~/storage ]]; then
			print_success "Storage configured successfully"
			break
		else
			print_failed "Storage permission denied"
		fi
		sleep 3
	done
	cd "$TERMUX_HOME" || return
	termux-reload-settings
	directories=(Music Pictures Videos)
	for dir in "${directories[@]}"; do
		check_and_create_directory "/sdcard/$dir"
	done
	check_and_create_directory "$TERMUX_HOME/Desktop"
	ln -s "$TERMUX_HOME/storage/shared/Music" "$TERMUX_HOME/"
	ln -s "$TERMUX_HOME/storage/shared/Pictures" "$TERMUX_HOME/"
	ln -s "$TERMUX_HOME/storage/shared/Videos" "$TERMUX_HOME/"
}

function setup_mic_permission() {
	if [[ "$IS_TERMUX_API_INSTALLED" == true ]]; then
		print_msg "Setting up mic permission..."
		echo
		print_msg "Please grant mic permission"
		echo
		sleep 2
		termux-microphone-record -l 1 -f /dev/null >/dev/null 2>&1 &
		sleep 5
	else
		print_msg "You can't use microphone because you didn't install Termux-Api apk"
		sleep 3
	fi

}

function setup_necessary_permissions() {
	setup_folder
	setup_mic_permission
}

#########################################################################
#
# Hardware Acceleration Setup
#
#########################################################################

# setup hardware acceleration, check if the enable-hw-acceleration already exist, if then first check if it different from github , then ask user if they want to replace it with the latest or not, if not then continue with the local enable-hw-acceleration file
function get_hw_acceleration_source() {
	local script_path="${current_path}/enable-hw-acceleration"
	local remote_url="$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/enable-hw-acceleration"

	if [[ -f "$script_path" ]]; then
		local current_script_hash
		current_script_hash=$(curl -sL "$remote_url" | sha256sum | cut -d ' ' -f 1)

		# Add error checking for remote fetch
		if [[ -z "$current_script_hash" ]]; then
			print_msg "Failed to fetch remote script for comparison. Using local version."
			chmod +x "$script_path"
			return
		fi

		local local_script_hash
		local_script_hash=$(sha256sum "$script_path" | cut -d ' ' -f 1)

		if [[ "$local_script_hash" != "$current_script_hash" ]]; then
			print_msg "A different version of the hardware acceleration installer is detected."
			echo
			confirmation_y_or_n "Do you want to replace it with the latest version?" change_old_hw_installer
			# shellcheck disable=SC2154
			if [[ "$change_old_hw_installer" == "y" ]]; then
				check_and_backup "$script_path"
				download_file "$script_path" "$remote_url"
			else
				print_msg "Using the local hardware acceleration setup file."
			fi
			print_to_config "change_old_hw_installer"
		else
			print_msg "Using the local hardware acceleration setup file."
		fi
	else
		download_file "$script_path" "$remote_url"
	fi

	chmod +x "$script_path"
}

function hw_config() {
	banner
	print_msg "${BOLD}Configuring Hardware Acceleration"
	echo
	print_to_config "enable_hw_acc"

	# Get the hardware acceleration source
	get_hw_acceleration_source

	# Source the script
	# shellcheck disable=SC1091
	source "${current_path}/enable-hw-acceleration"

	# Call the main hardware acceleration setup function
	run_hw_acceleration_setup_main

	# Clean up
	check_and_delete "${current_path}/enable-hw-acceleration"
	log_debug "$current_path $current_script_hash $local_script_hash"
}

#########################################################################
#
# Proot Distro Setup
#
#########################################################################

# same as the hardware acceleration setup but for distro-container-setup file
function get_distro_container_source() {
	local script_path="${current_path}/distro-container-setup"
	local remote_url="$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/distro-container-setup"

	if [[ -f "$script_path" ]]; then
		local current_script_hash
		current_script_hash=$(curl -sL "$remote_url" | sha256sum | cut -d ' ' -f 1)
		local local_script_hash
		local_script_hash=$(sha256sum "$script_path" | cut -d ' ' -f 1)

		if [[ "$local_script_hash" != "$current_script_hash" ]]; then
			print_msg "It looks like you already have a different distro-container setup script in your current directory"
			echo
			confirmation_y_or_n "Do you want to change it with the latest installer" change_old_distro_installer
			# shellcheck disable=SC2154
			if [[ "$change_old_distro_installer" == "y" ]]; then
				check_and_backup "$script_path"
				download_file "$script_path" "$remote_url"
			else
				print_msg "Using the local distro-container setup file"
			fi
			print_to_config "change_old_distro_installer"
		else
			print_msg "Using the local distro-container setup file"
		fi
	else
		download_file "$script_path" "$remote_url"
	fi

	chmod +x "$script_path"
}

function distro_container_setup() {
	print_to_config "distro_add_answer"
	if [[ "$distro_add_answer" == "n" ]]; then
		banner
		print_msg "${C}Skipping Linux Distro Container Setup..."
		echo
		if [[ "$enable_hw_acc" == "y" ]]; then
			hw_config
		else
			print_to_config "enable_hw_acc"
		fi
	else
		banner
		print_msg "${BOLD}Configuring Linux Distro Container"
		echo

		# Get the distro container source
		get_distro_container_source

		# Source the script
		# shellcheck disable=SC1091
		source "${current_path}/distro-container-setup"

		# Call the main distro container setup function
		run_distro_container_setup_main

		# Clean up
		check_and_delete "${current_path}/distro-container-setup"
	fi
	log_debug "$current_path $distro_add_answer $local_script_hash"
}

#########################################################################
#
# Vnc | Termux:x11 | Launch Scripts
#
#########################################################################

function setup_vncstart_cmd() {
	check_and_delete "$TERMUX_PREFIX/bin/vncstart"
	if [[ "$enable_hw_acc" == "n" ]]; then
		cat <<-EOF >"$TERMUX_PREFIX/bin/vncstart"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "vncstart command should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID

			termux-wake-lock

			# Prevent script from looping by checking if it's already running
			if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
			  if pgrep -f "vncserver" >/dev/null; then
			    echo "[!] vncserver is already running. Exiting."
			    exit 1
			  fi
			fi

			vnc_server_pid=\$(pgrep -f "vncserver")
			de_pid=\$(pgrep -f "$de_startup")

			if [[ -n "\$de_pid" || -n "\$vnc_server_pid" ]]; then
			    vncstop -f
			fi

			if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
			      if \$use_debug; then
			          rm -rf ~/.config/pulse/*-runtime/pid
			      else
			          rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
			      fi
			    pulseaudio --start --exit-idle-time=-1
			    pactl load-module module-sles-source > /dev/null 2>&1
			fi

			function show_vncstart_help() {
				cat <<HELP_EOF
				Usage:

				vncstart            - start vncserver
				vncstart --help     - show help
				HELP_EOF
			}

			case \$1 in
			    --help|-h)
			        show_vncstart_help
			        ;;
			    *)
			        if [[ -n "\$1" ]]; then
			            echo "[☓] Invalid option: \$1"
			            show_vncstart_help
			        else
			            env XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg vncserver
			        fi
			        ;;
			esac
		EOF
	elif [[ "$enable_hw_acc" == "y" ]]; then
		cat <<-EOF >"$TERMUX_PREFIX/bin/vncstart"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "vncstart command should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID

			termux-wake-lock

			# Prevent script from looping by checking if it's already running
			if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
			  if pgrep -f "vncserver" >/dev/null; then
			    echo "[!] vncserver is already running. Exiting."
			    exit 1
			  fi
			fi

			vnc_server_pid=\$(pgrep -f "vncserver")
			de_pid=\$(pgrep -f "$de_startup")

			if [[ -n "\$de_pid" || -n "\$vnc_server_pid" ]]; then
			    vncstop -f
			fi

			if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
			      if \$use_debug; then
			          rm -rf ~/.config/pulse/*-runtime/pid
			      else
			          rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
			      fi
			    pulseaudio --start --exit-idle-time=-1
			    pactl load-module module-sles-source > /dev/null 2>&1
			fi

			function show_vncstart_help() {
				cat <<HELP_EOF
				Usage:

				vncstart            - start vncserver with GPU acceleration
				vncstart --nogpu    - start vncserver without GPU acceleration
				vncstart --help     - show this help message
				HELP_EOF
			}

			case \$1 in
			    --nogpu)
			        env XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg LIBGL_ALWAYS_SOFTWARE=1 MESA_LOADER_DRIVER_OVERRIDE=llvmpipe GALLIUM_DRIVER=llvmpipe vncserver
			        ;;
			    --help|-h)
			        show_vncstart_help
			        ;;
			    *)
			        if [[ -n "\$1" ]]; then
			            echo "[☓] Invalid option: \$1"
			            show_vncstart_help
			        else
			            export ${set_to_export}
			            ${initialize_server_method} &
			            env XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg $hw_method vncserver
			        fi
			        ;;
			esac
		EOF
	fi
	chmod +x "$TERMUX_PREFIX/bin/vncstart"
}

function setup_vncstop_cmd() {
	check_and_delete "$TERMUX_PREFIX/bin/vncstop"
	cat <<-EOF >"$TERMUX_PREFIX/bin/vncstop"
		#!/data/data/com.termux/files/usr/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
		TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d $'\t' -f 2)
		if [ "\$TRACER_PID" != 0 ]; then
			TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_NAME" = "proot" ]; then
				msg
				print_failed "vncstop command should not be executed under PRoot."
				msg
				exit 1
			fi
			unset TRACER_NAME
		fi
		unset TRACER_PID

		termux-wake-unlock

		# Function to clean up VNC files
		cleanup_vnc_files() {
		    # Clean up .vnc log files
		    if [ -d "$TERMUX_HOME/.vnc" ]; then
		        rm -f "$TERMUX_HOME/.vnc/localhost:"*.log > /dev/null 2>&1
		        rm -f "$TERMUX_HOME/.vnc/"*.log > /dev/null 2>&1
		    fi

		    # Clean up X lock files (X1-lock, X2-lock, etc.)
		    if [ -d "$TERMUX_PREFIX/tmp" ]; then
		        rm -f "$TERMUX_PREFIX/tmp/.X"*"-lock" > /dev/null 2>&1
		    fi

		    # Clean up X11 socket files (X1, X2, etc.)
		    if [ -d "$TERMUX_PREFIX/tmp/.X11-unix" ]; then
		        rm -f "$TERMUX_PREFIX/tmp/.X11-unix/X"* > /dev/null 2>&1
		    fi
		}

		# Function to force kill all VNC processes
		force_kill_vnc() {
		    print_msg "Force terminating all VNC processes..."
		    print_msg "Killing processes..."

		    # Kill Xtigervnc processes
		    pkill -9 Xtigervnc > /dev/null 2>&1
		    pkill -9 vncserver > /dev/null 2>&1
		    pkill -9 vnc > /dev/null 2>&1
		    pkill -9 "X[0-9]*" > /dev/null 2>&1

		    sleep 0.5
		    print_msg "Cleaning up files..."
		    cleanup_vnc_files
		    sleep 0.5
		    print_success "All VNC processes terminated and cleaned up"
		}

		# Function to gracefully stop VNC servers
		graceful_stop() {
		    # Try to get display numbers from vncserver -list
		    display_numbers=\$(vncserver -list 2>/dev/null | grep -oE ':[0-9]+' | sort -u)

		    if [ -n "\$display_numbers" ]; then
		        # Convert to array and format nicely
		        display_array=(\$display_numbers)
		        display_count=\${#display_array[@]}
		        # Remove colons and create comma-separated list
		        display_list=""
		        for i in "\${!display_array[@]}"; do
		            num=\${display_array[i]#:}
		            if [ \$i -eq 0 ]; then
		                display_list="\$num"
		            else
		                display_list="\$display_list, \$num"
		            fi
		        done

		        print_msg "Found active VNC displays: \$display_list"

		        local count=0
		        for display in \$display_numbers; do
		            count=\$((count + 1))
		            display_num=\${display#:}
		            print_msg "Stopping VNC server on display \$display_num (\$count/\$display_count)..."
		            vncserver -kill "\$display" 2>/dev/null
		            sleep 0.2
		            print_success "Stopped VNC server on display \$display_num (\$count/\$display_count)"
		            sleep 0.3
		        done
		    else
		        # Check for stale lock files
		        if [ -d "$TERMUX_PREFIX/tmp" ]; then
		            lock_files=\$(find "$TERMUX_PREFIX/tmp" -name ".X*-lock" -type f 2>/dev/null | sed 's/.*\.X\([0-9]*\)-.*/:\1/' | sort -u)
		            if [ -n "\$lock_files" ]; then
		                lock_array=(\$lock_files)
		                lock_count=\${#lock_array[@]}
		                # Remove colons and create comma-separated list
		                lock_list=""
		                for i in "\${!lock_array[@]}"; do
		                    num=\${lock_array[i]#:}
		                    if [ \$i -eq 0 ]; then
		                        lock_list="\$num"
		                    else
		                        lock_list="\$lock_list, \$num"
		                    fi
		                done

		                print_msg "Found stale displays: \$lock_list"

		                local count=0
		                for display in \$lock_files; do
		                    count=\$((count + 1))
		                    display_num=\${display#:}
		                    print_msg "Cleaning stale display \$display_num (\$count/\$lock_count)..."
		                    vncserver -kill "\$display" 2>/dev/null || true
		                    sleep 0.2
		                    print_success "Cleaned stale display \$display_num (\$count/\$lock_count)"
		                    sleep 0.3
		                done
		            else
		                print_msg "No VNC displays found"
		                return
		            fi
		        fi
		    fi

		    # Handle any remaining stubborn processes
		    if pgrep -x "Xtigervnc" > /dev/null 2>&1; then
		        print_msg "Terminating remaining processes..."
		        pkill Xtigervnc > /dev/null 2>&1
		        sleep 1
		        if pgrep -x "Xtigervnc" > /dev/null 2>&1; then
		            pkill -9 Xtigervnc > /dev/null 2>&1
		        fi
		        sleep 0.5
		    fi

		    cleanup_vnc_files
		    print_success "VNC cleanup completed"
		}

		# Main script logic
		if [[ "\$1" == "-f" ]] || [[ "\$1" == "--force" ]]; then
		    force_kill_vnc
		elif [[ "\$1" == "-h" ]] || [[ "\$1" == "--help" ]]; then
			cat <<HELP_EOF
			VNC Server Manager

			vncstop           - gracefully stop all VNC servers
			vncstop --force   - force terminate all VNC servers
			vncstop --help    - show this help
			HELP_EOF
		else
		    graceful_stop
		fi
	EOF
	chmod +x "$TERMUX_PREFIX/bin/vncstop"
}

function setup_vnc() {
	banner
	print_msg "${BOLD}Configuring Vnc..."
	echo
	package_install_and_check "tigervnc"
	check_and_create_directory "$TERMUX_HOME/.vnc"
	check_and_delete "$TERMUX_HOME/.vnc/xstartup"
	cat <<-EOF >"$TERMUX_HOME/.vnc/xstartup"
		    $de_startup &
	EOF
	chmod +x "$TERMUX_HOME/.vnc/xstartup"
	setup_vncstart_cmd
	setup_vncstop_cmd
}

function setup_tx11start_cmd() {
	check_and_delete "$TERMUX_PREFIX/bin/tx11start"
	if [[ "$enable_hw_acc" == "y" ]]; then

		cat <<-EOF >"$TERMUX_PREFIX/bin/tx11start"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "tx11start command should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID

			    # Initialize flags
			    use_nogpu=false
			    use_nodbus=false
			    use_legacy=false
			    use_debug=false
			    de_startup="$de_startup"

			    # Function to show help
			    function show_tx11start_help() {
					cat <<HELP_EOF
					tx11start                               - start Termux:X11 with GPU acceleration
					tx11start --nogpu                       - start without GPU acceleration
					tx11start --nodbus                      - start without dbus
					tx11start --legacy                      - start with -legacy-drawing
					tx11start --debug                       - show debug log
					tx11start --xstartup "xstartup-name"    - launch another desktop environment
					HELP_EOF
					exit 0
				}

			    # Parse arguments
			    while ((\$# >= 1)); do
			      case "\$1" in
			      --help)
			        show_tx11start_help
			        ;;
			      --xstartup | -xstartup)
			          shift
			          de_startup="\$1"
			          echo "\$de_startup" > "$TERMUX_HOME/.xstartup"
			          ;;
			      --nogpu | --no-gpu)
			        use_nogpu=true
			        ;;
			      --nodbus | --no-dbus)
			        use_nodbus=true
			        ;;
			      --legacy)
			        use_legacy=true
			        ;;
			      --debug)
			        use_debug=true
			        ;;
			      *)
			        echo "Invalid option: \$1"
			        show_tx11start_help
			        ;;
			      esac
			      shift
			    done

			    # Kill existing Termux X11 processes
			    pkill -f com.termux.x11 >/dev/null 2>&1
			    pkill -9 "\$de_startup" >/dev/null 2>&1

			    # Ensure XDG_RUNTIME_DIR exists
			    export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp
			    mkdir -p "\$XDG_RUNTIME_DIR"

			    # Export DISPLAY variable
			    export DISPLAY=:${display_number}

			    # Start pulseaudio unless --help was given
			    if [[ "\$1" != "--help" ]]; then
			      termux-wake-lock
			      if \$use_debug; then
			          rm -rf ~/.config/pulse/*-runtime/pid
			      else
			          rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
			      fi
			      # pulseaudio --start --load="module-aaudio-sink" --exit-idle-time=-1
			      pulseaudio --start --exit-idle-time=-1
			      pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
			      if \$use_debug; then
			        pactl load-module module-sles-source
			      else
			        pactl load-module module-sles-source >/dev/null 2>&1
			      fi
			    fi

			    # Set environment variables if NOT using --nogpu
			    if ! \$use_nogpu; then
			      export ${set_to_export}
			      if \$use_debug; then
			        ${initialize_server_method} &
			      else
			        ${initialize_server_method} >/dev/null 2>&1 &
			      fi
			      export ${gpu_environment_variable} ${hw_method}
			  else
			        export LIBGL_ALWAYS_SOFTWARE=1 MESA_LOADER_DRIVER_OVERRIDE=llvmpipe GALLIUM_DRIVER=llvmpipe
			    fi

			    sleep 1

			    # Construct X11 command
			    # x11_cmd="XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR} termux-x11 :0" # Comment this because i found that the sound doesn't working if i set this XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR}
			     if \$use_nogpu; then
			         x11_cmd="LIBGL_ALWAYS_SOFTWARE=1 termux-x11 :0"
			     else
			         x11_cmd="termux-x11 :0"
			     fi

			    if \$use_legacy; then
			      x11_cmd+=" -legacy-drawing"
			    fi

			    # Start X11
			    if \$use_debug; then
			      eval "\$x11_cmd" &
			    else
			      eval "\$x11_cmd" >/dev/null 2>&1 &
			    fi
			    sleep 1

			    # Start X11 Main Activity
			    if \$use_debug; then
			      am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity
			    else
			      am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity >/dev/null 2>&1
			    fi
			    sleep 1

			    # Start the desktop environment
			    if \$use_nodbus; then
			      if \$use_debug; then
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg \$de_startup &
			      else
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg \$de_startup >/dev/null 2>&1 &
			      fi
			    else
			      if \$use_debug; then
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg dbus-launch --exit-with-session \$de_startup &
			      else
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg dbus-launch --exit-with-session \$de_startup >/dev/null 2>&1 &
			      fi
			    fi

		EOF

	elif [[ "$enable_hw_acc" == "n" ]]; then

		cat <<-EOF >"$TERMUX_PREFIX/bin/tx11start"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "tx11start command should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID

			    # Initialize flags
			    use_nodbus=false
			    use_legacy=false
			    use_debug=false
			    de_startup="$de_startup"

			    # Function to show help
				function show_tx11start_help() {
					cat <<HELP_EOF
					tx11start                               - start Termux:X11
					tx11start --nodbus                      - start without dbus
					tx11start --legacy                      - start with -legacy-drawing
					tx11start --debug                       - show debug log
					tx11start --xstartup "xstartup-name"    - launch another desktop environment
					HELP_EOF
					exit 0
				}

			    # Parse arguments
			    while ((\$# >= 1)); do
			      case "\$1" in
			      --help)
			        show_tx11start_help
			        ;;
			      --xstartup | -xstartup)
			          shift
			          de_startup="\$1"
			          echo "\$de_startup" > "$TERMUX_HOME/.xstartup"
			          ;;
			      --nodbus | --no-dbus)
			        use_nodbus=true
			        ;;
			      --legacy)
			        use_legacy=true
			        ;;
			      --debug)
			        use_debug=true
			        ;;
			      *)
			        echo "Invalid option: \$1"
			        show_tx11start_help
			        ;;
			      esac
			      shift
			    done

			    # Kill existing Termux X11 processes
			    pkill -f com.termux.x11 >/dev/null 2>&1
			    pkill -9 "\$de_startup" >/dev/null 2>&1

			    # Ensure XDG_RUNTIME_DIR exists
			    export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp
			    mkdir -p "\$XDG_RUNTIME_DIR"

			    # Export DISPLAY variable
			    export DISPLAY=:${display_number}

			    # Start pulseaudio unless --help was given
			    if [[ "\$1" != "--help" ]]; then
			      termux-wake-lock
			      if \$use_debug; then
			          rm -rf ~/.config/pulse/*-runtime/pid
			      else
			          rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
			      fi
			      # pulseaudio --start --load="module-aaudio-sink" --exit-idle-time=-1
			      pulseaudio --start --exit-idle-time=-1
			      pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
			      if \$use_debug; then
			        pactl load-module module-sles-source
			      else
			        pactl load-module module-sles-source >/dev/null 2>&1
			      fi
			    fi

			    # Construct X11 command
			    # x11_cmd="XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR} termux-x11 :0" # Comment this because i found that the sound doesn't working if i set this XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR}
			    x11_cmd="termux-x11 :0"

			    if \$use_legacy; then
			      x11_cmd+=" -legacy-drawing"
			    fi

			    # Start X11
			    if \$use_debug; then
			      eval "\$x11_cmd" &
			    else
			      eval "\$x11_cmd" >/dev/null 2>&1 &
			    fi
			    sleep 1

			    # Start X11 Main Activity
			    if \$use_debug; then
			      am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity
			    else
			      am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity >/dev/null 2>&1
			    fi
			    sleep 1

			    # Start the desktop environment
			    if \$use_nodbus; then
			      if \$use_debug; then
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg \$de_startup &
			      else
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg \$de_startup >/dev/null 2>&1 &
			      fi
			    else
			      if \$use_debug; then
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg dbus-launch --exit-with-session \$de_startup &
			      else
			        env DISPLAY=:${display_number} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg dbus-launch --exit-with-session \$de_startup >/dev/null 2>&1 &
			      fi
			    fi

		EOF

	fi

	if [[ "$de_name" == "xfce" ]]; then
		cat <<-EOF >>"$TERMUX_PREFIX/bin/tx11start"
			# Kill xfce4-screensaver if running
			sleep 5
			process_id=\$(ps aux | grep '[x]fce4-screensaver' | awk '{print \$2}')
			if [[ -n "\$process_id" ]]; then
				if \$use_debug; then
					kill "\$process_id"
				else
			     kill "\$process_id" > /dev/null 2>&1
				fi
			fi
		EOF
	fi
	chmod +x "$TERMUX_PREFIX/bin/tx11start"
}

function setup_tx11stop_cmd() {
	check_and_delete "$TERMUX_PREFIX/bin/tx11stop"
	if [[ "$de_name" == "openbox" ]]; then
		cat <<-EOF >"$TERMUX_PREFIX/bin/tx11stop"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "tx11stop command should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID

			termux-wake-unlock

			if [[ -f "$TERMUX_HOME/.xstartup" ]]; then
			    de_startup=\$(cat "$TERMUX_HOME/.xstartup")
			else
			    de_startup="$de_startup"
			fi

			termux_x11_pid=\$(pgrep -f "/system/bin/app_process / com.termux.x11.Loader :${display_number}")
			de_pid=\$(pgrep -f \$de_startup)
			if [[ -n "\$termux_x11_pid" ]] || [[ -n "\$de_pid" ]]; then
			kill -9 "\$termux_x11_pid" > /dev/null 2>&1
			pkill -9 pulseaudio > /dev/null 2>&1
			killall virgl_test_server > /dev/null 2>&1
			pkill -9 openbox* > /dev/null 2>&1
			pkill -9 dbus-* > /dev/null 2>&1
			pkill -f com.termux.x11 > /dev/null 2>&1
			sleep 1
				if [[ ! -n "\$termux_x11_pid" ]] || [[ ! -n "\$de_pid" ]]; then
				echo -e "${G}Termux:X11 Stopped Successfully ${NC}"
			    [[ -f "$TERMUX_HOME/.xstartup" ]] && rm -rf "$TERMUX_HOME/.xstartup"
				fi
			elif [[ "\$1" == "-f" ]] || [[ "\$1" == "--force" ]]; then
			pkill -f com.termux.x11 > /dev/null 2>&1
			pkill -9 openbox* > /dev/null 2>&1
			killall virgl_test_server > /dev/null 2>&1
			pkill -9 pulseaudio > /dev/null 2>&1
			pkill -9 dbus-* > /dev/null 2>&1
			echo -e "${G}Termux:X11 Successfully Force Stopped ${NC}"
			[[ -f "$TERMUX_HOME/.xstartup" ]] && rm -rf "$TERMUX_HOME/.xstartup"
			elif [[ "\$1" == "-h" ]]; then
			echo -e "tx11stop       to stop termux:x11"
			echo -e "tx11stop -f    to kill termux:x11"
			fi
			exec 2>/dev/null
		EOF
	else

		cat <<-EOF >"$TERMUX_PREFIX/bin/tx11stop"
			#!/data/data/com.termux/files/usr/bin/bash

			source $TERMUX_PREFIX/etc/termux-desktop/common_functions

			# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
			TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
			if [ "\$TRACER_PID" != 0 ]; then
				TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
				if [ "\$TRACER_NAME" = "proot" ]; then
					msg
					print_failed "tx11stop command should not be executed under PRoot.\${W}"
					msg
					exit 1
				fi
				unset TRACER_NAME
			fi
			unset TRACER_PID

			termux-wake-unlock

			if [[ -f "$TERMUX_HOME/.xstartup" ]]; then
			    de_startup=\$(cat "$TERMUX_HOME/.xstartup")
			else
			    de_startup="$de_startup"
			fi

			termux_x11_pid=\$(pgrep -f "/system/bin/app_process / com.termux.x11.Loader :${display_number}")
			de_pid=\$(pgrep -f \$de_startup)
			if [[ -n "\$termux_x11_pid" ]] || [[ -n "\$de_pid" ]]; then
			kill -9 "\$termux_x11_pid" > /dev/null 2>&1
			pkill -9 pulseaudio > /dev/null 2>&1
			killall virgl_test_server > /dev/null 2>&1
			pkill -9 $de_name-* > /dev/null 2>&1
			pkill -9 dbus-* > /dev/null 2>&1
			pkill -f com.termux.x11 > /dev/null 2>&1
				if [[ ! -n "\$termux_x11_pid" ]] || [[ ! -n "\$de_pid" ]]; then
				echo -e "${G}Termux:X11 Stopped Successfully ${NC}"
			    [[ -f "$TERMUX_HOME/.xstartup" ]] && rm -rf "$TERMUX_HOME/.xstartup"
				fi
			elif [[ "\$1" == "-f" ]] || [[ "\$1" == "--force" ]]; then
			pkill -f com.termux.x11 > /dev/null 2>&1
			pkill -9 $de_name-* > /dev/null 2>&1
			killall virgl_test_server > /dev/null 2>&1
			pkill -9 pulseaudio > /dev/null 2>&1
			pkill -9 dbus-* > /dev/null 2>&1
			echo -e "${G}Termux:X11 Successfully Force Stopped ${NC}"
			[[ -f "$TERMUX_HOME/.xstartup" ]] && rm -rf "$TERMUX_HOME/.xstartup"
			elif [[ "\$1" == "-h" ]]; then
			echo -e "tx11stop       to stop termux:x11"
			echo -e "tx11stop -f    to kill termux:x11"
			fi
			exec 2>/dev/null
		EOF
	fi
	chmod +x "$TERMUX_PREFIX/bin/tx11stop"
}

function setup_termux_x11() {
	banner
	print_msg "${BOLD}Configuring Termux:X11"
	echo
	package_install_and_check "termux-x11-nightly"
	local repo_owner="termux"
	local repo_name="termux-x11"
	local latest_termux_x11_tag
	latest_termux_x11_tag=$(get_latest_release "termux" "termux-x11")
	local termux_x11_url="https://github.com/$repo_owner/$repo_name/releases/download/$latest_termux_x11_tag/"
	local assets
	assets=$(curl -s "https://api.github.com/repos/$repo_owner/$repo_name/releases/latest" | grep -oP '(?<="name": ")[^"]*')
	deb_assets=$(echo "$assets" | grep "termux-x11.*all.deb")
	download_file "$current_path/termux-x11.deb" "$termux_x11_url/$deb_assets"
	apt install "$current_path/termux-x11.deb" -y
	rm "$current_path/termux-x11.deb"
	# "sed -i '12s/^#//' "$TERMUX_HOME/.termux/termux.properties"
	setup_tx11start_cmd
	setup_tx11stop_cmd
}

function gui_termux_x11() {
	cat <<-EOF >"$TERMUX_PREFIX/bin/gui"
		#!/data/data/com.termux/files/usr/bin/bash

		source "$TERMUX_PREFIX/etc/termux-desktop/common_functions"

		# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
		TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d $'\t' -f 2)
		if [ "\$TRACER_PID" != 0 ]; then
		    TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d $'\t' -f 2)
		    if [ "\$TRACER_NAME" = "proot" ]; then
		        msg
		        print_failed "gui command should not be executed under PRoot.\${W}"
		        msg
		        exit 1
		    fi
		    unset TRACER_NAME
		fi
		unset TRACER_PID

		forward_display() {
		    print_msg "Starting display on: \${given_ip}:\${display_port} \${NC}"
		    pkill -9 "$de_startup" >/dev/null 2>&1
		    pulseaudio --start --exit-idle-time=-1
		    pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
		    rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
		    pactl load-module module-sles-source >/dev/null 2>&1
		    export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp
		    mkdir -p "\$XDG_RUNTIME_DIR"
		    env DISPLAY=\${given_ip}:\${display_port} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg dbus-launch --exit-with-session $de_startup
		}

		case \$1 in
		--start | -l)
		    tx11start
		    ;;
		--display | -d)
		    if [[ "\$2" == *":"* ]]; then
		        # Everything before the last colon
		        given_ip="\${2%:*}"
		        # Everythingg after the last colon
		        display_port="\${2##*:}"
		    else
		        given_ip="\$2"
		        display_port="0"
		    fi

		    if [ -z "\$given_ip" ]; then
		        print_failed "No IP address provided"
		        echo -e "Usage: gui --display <IP_ADDRESS>[:<PORT>]\nExamples:\n  gui --display 192.168.1.100:0\n  gui --display 192.168.1.100"
		        exit 1
		    fi
		    forward_display
		    unset given_ip display_port
		    ;;
		--stop | -s)
		    tx11stop
		    ;;
		--kill | -k | -kill)
		    tx11stop -f
		    print_success "gui services killed successfully"
		    ;;
			--help | -h)
		cat <<HELP_EOF
		Usage: gui [OPTION]

		Options:
		  --start, -l                                 - start termux:x11
		  --display, -d <IP_ADDRESS:DISPLAY_PORT]>    - forward display to IP address
		  --stop, -s                                  - stop termux:x11
		  --kill, -k                                  - kill gui services
		HELP_EOF
		;;

		*)
		    echo "${R}Invalid choise${NC}"
		    gui -h
		    ;;
		esac
	EOF
}

function gui_both() {
	cat <<-EOF >"$TERMUX_PREFIX/bin/gui"
		#!/data/data/com.termux/files/usr/bin/bash

		source $TERMUX_PREFIX/etc/termux-desktop/common_functions

		# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
		TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d $'\t' -f 2)
		if [ "\$TRACER_PID" != 0 ]; then
		    TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d $'\t' -f 2)
		    if [ "\$TRACER_NAME" = "proot" ]; then
		        msg
		        print_failed "gui command should not be executed under PRoot.\${W}"
		        msg
		        exit 1
		    fi
		    unset TRACER_NAME
		fi
		unset TRACER_PID

		forward_display() {
		    print_msg "Starting display on: \${given_ip}:\${display_port}"
		    pkill -9 "$de_startup" >/dev/null 2>&1
		    pulseaudio --start --exit-idle-time=-1
		    pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
		    rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
		    pactl load-module module-sles-source >/dev/null 2>&1
		    export XDG_RUNTIME_DIR=$TERMUX_PREFIX/tmp
		    mkdir -p "\$XDG_RUNTIME_DIR"
		    env DISPLAY=\${given_ip}:\${display_port} XDG_CONFIG_DIRS=$TERMUX_PREFIX/etc/xdg dbus-launch --exit-with-session $de_startup &
		}

		case \$1 in
		--start | -l)
		    case \$2 in
		    tx11)
		        tx11start
		        ;;
		    vnc)
		        vncstart
		        ;;
		    *)
		        echo -e "\${R}Invalid choise. Use \${C}tx11\${R} or \${C}vnc \${G}with it\${NC}"
		        ;;
		    esac
		    ;;
		--display | -d)
		    if [[ "\$2" == *":"* ]]; then
		        # Everything before the last colon
		        given_ip="\${2%:*}"
		        # Everything after the last colon
		        display_port="\${2##*:}"
		    else
		        given_ip="\$2"
		        display_port="0"
		    fi

		    if [ -z "\$given_ip" ]; then
		        print_failed "No IP address provided"
		        echo -e "Usage: gui --display <IP_ADDRESS>[:<PORT>]\nExamples:\n  gui --display 192.168.1.100:0\n  gui --display 192.168.1.100"
		        exit 1
		    fi
		    forward_display
		    unset given_ip display_port
		    ;;
		--kill | -k | -kill)
		    vncstop -f >/dev/null 2>&1
		    tx11stop -f >/dev/null 2>&1
		    print_success "gui services killed successfully"
		    ;;
		--stop | -s)
		    case \$2 in
		    tx11)
		        tx11stop
		        ;;
		    vnc)
		        vncstop
		        ;;
		    *)
		        echo -e "\${R}Invalid choise. Use \${C}tx11\${R} or \${C}vnc \${G}with it\${NC}"
		        ;;
		    esac
		    ;;
			--help | -h)
		cat <<HELP_EOF
		Usage: gui [OPTION] [ARGUMENT]

		Options:
		  --start, -l [tx11/vnc]                      - start a GUI (termux:x11 or VNC)
		  --display, -d <IP_ADDRESS:DISPLAY_PORT]>    - forward display to IP address
		  --stop, -s [tx11/vnc]                       - stop a GUI (termux:x11 or VNC)
		  --kill, -k                                  - kill both GUI services at once
		  --help, -h                                  - show this help message
		HELP_EOF
		;;
		*)
		    echo -e "\${R}Invalid choice\${NC}"
		    gui -h
		    ;;
		esac
	EOF
}

function gui_launcher() {
	check_and_delete "$TERMUX_PREFIX/bin/gui"
	package_install_and_check "xorg-xhost"
	if [[ "$gui_mode" == "termux_x11" ]]; then
		setup_termux_x11
		gui_termux_x11
	elif [[ "$gui_mode" == "both" ]]; then
		setup_termux_x11
		setup_vnc
		gui_both
	else
		setup_termux_x11
		gui_termux_x11
	fi
	print_to_config "gui_mode"
	print_to_config "display_number"
	chmod +x "$TERMUX_PREFIX/bin/gui"
	check_and_create_directory "$TERMUX_PREFIX/share/applications/"
	cat <<-EOF >"$TERMUX_PREFIX/share/applications/killgui.desktop"
		[Desktop Entry]
		Version=1.0
		Type=Application
		Name=Stop Desktop
		Comment=Kill or stop termux desktop
		Exec=gui --kill
		Icon=system-shutdown
		Categories=System;
		Path=
		Terminal=false
		StartupNotify=false
	EOF
	chmod 644 "$TERMUX_PREFIX/share/applications/killgui.desktop"
	cp "$TERMUX_PREFIX/share/applications/killgui.desktop" "$TERMUX_HOME/Desktop/"
}

function check_desktop_process() {
	banner
	print_msg "Checking Termux:X11 and $de_name setup or not..."
	echo
	sleep 0.5
	# check tx11start file and start termux x11 to check termux x11 process
	if [[ -f "${PREFIX}/bin/tx11start" ]]; then
		print_success "Found tx11start file."
		print_msg "Starting Termux:X11 for checkup..."
		termux-x11 :"${display_number}" -xstartup xfce4-session >/dev/null 2>&1 &
		sleep 10
		log_debug "$(cat "$TERMUX_PREFIX/bin/tx11start")"
		termux-reload-settings
		local termux_x11_pid
		termux_x11_pid=$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
		if [[ -n "$termux_x11_pid" ]]; then
			print_success "Termux:X11 Working"
		else
			print_failed "No Termux:X11 process found"
		fi

		# check for the desktop environment related process
		local de_pid
		case "$de_name" in
		xfce)
			de_pid="$(pgrep xfce4)"
			;;
		lxqt)
			de_pid="$(pgrep -f "lxqt-session|lxqt-panel")"
			;;
		gnome)
			de_pid="$(pgrep -f "gnome-session-minimal|gnome-session")"
			;;
		cinnamon)
			de_pid="$(pgrep -f "cinnamon-session")"
			;;
		openbox)
			de_pid="$(pgrep -f "openbox|openbox-session")"
			;;
		mate)
			de_pid="$(pgrep -f "mate-session|mate-panel")"
			;;
		i3)
			de_pid="$(pgrep -f "i3|i3-with-shmlog")"
			;;
		dwm)
			de_pid="$(pgrep dwm)"
			;;
		bspwm)
			de_pid="$(pgrep bspwm)"
			;;
		awesome)
			de_pid="$(pgrep -f awesome)"
			;;
		fluxbox)
			de_pid="$(pgrep -f fluxbox)"
			;;
		icewm)
			de_pid="$(pgrep -f icewm-session)"
			;;
		*)
			print_failed "Unknown desktop environment: $de_name"
			sleep 0.2
			return 1
			;;
		esac

		if [[ -n "$de_pid" ]]; then
			print_success "$de_name is running fine"
			sleep 0.2
		else
			print_failed "No $de_name process found, attempting to reinstall..."
			sleep 0.2
			install_desktop

			# Check again after installation
			unset de_pid
			case "$de_name" in
			xfce)
				de_pid="$(pgrep xfce4)"
				;;
			lxqt)
				de_pid="$(pgrep -f "lxqt-session|lxqt-panel|pcmanfm-qt")"
				;;
			openbox)
				de_pid="$(pgrep -f "openbox|openbox-session")"
				;;
			mate)
				de_pid="$(pgrep -f "mate-session|mate-panel|caja")"
				;;
			i3)
				de_pid="$(pgrep -f "i3|i3-with-shmlog")"
				;;
			dwm)
				de_pid="$(pgrep dwm)"
				;;
			bspwm)
				de_pid="$(pgrep bspwm)"
				;;
			awesome)
				de_pid="$(pgrep -f awesome)"
				;;
			fluxbox)
				de_pid="$(pgrep -f fluxbox)"
				;;
			*)
				print_failed "Unknown desktop environment: $de_name"
				sleep 0.2
				return 1
				;;
			esac

			if [[ -n "$de_pid" ]]; then
				print_success "$de_name is now running after re-installation"
				sleep 0.2
			else
				print_failed "$de_name failed to install or start, still after re-installation"
				sleep 0.2
				return 1
			fi
		fi

		# check tx11stop file and run it to check if there any termux x11 process exist or not
		if [[ -f "${PREFIX}/bin/tx11stop" ]]; then
			print_success "Found tx11stop file."
			log_debug "$(cat "$TERMUX_PREFIX/bin/tx11stop")"
			tx11stop -f
			# Wait a bit for the process to stop
			sleep 2
			unset termux_x11_pid
			termux_x11_pid=$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
			if [[ -z "$termux_x11_pid" ]]; then
				print_success "Tx11stop command working"
			else
				print_failed "Tx11stop command not working"
			fi
		fi
	fi
	print_msg "Backing up current Termux:x11 preferences..."
	echo
	termux-x11 &
	termux-x11-preference list >"$TERMUX_HOME/old-termx-x11-preferences"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termx-x11-preferences"
	print_msg "Adding custom Termux:x11 preferences..."
	echo
	termux-x11-preference <termx-x11-preferences
	pkill -f com.termux.x11 >/dev/null 2>&1
	check_and_delete "termx-x11-preferences"
}

#########################################################################
#
# Install Browser
#
#########################################################################

function browser_installer() {
	banner
	print_to_config "installed_browser"
	if [[ ${installed_browser} == "firefox" ]]; then
		package_install_and_check "firefox"
	elif [[ ${installed_browser} == "chromium" ]]; then
		package_install_and_check "chromium"
	elif [[ ${installed_browser} == "all" ]]; then
		package_install_and_check "firefox chromium"
	elif [[ ${installed_browser} == "skip" ]]; then
		print_msg "${C}Skipping Browser Installation..."
		echo
		sleep 2
	else
		package_install_and_check "firefox"
		print_to_config "installed_browser" "firefox"
	fi
}

#########################################################################
#
# Install Ide
#
#########################################################################

function ide_installer() {
	banner
	print_to_config "installed_ide"
	if [[ ${installed_ide} == "code" ]]; then
		package_install_and_check "code-oss code-is-code-oss"
	elif [[ ${installed_ide} == "geany" ]]; then
		package_install_and_check "geany"
	elif [[ ${installed_ide} == "neovim" ]]; then
		package_install_and_check "neovim lua51 lua-language-server stylua"
		package_install_and_check "tree-sitter-*"
		check_and_backup "$TERMUX_HOME/.config/nvim"
		if [[ "$installed_nvim_distro" == "nvchad" ]]; then
			git clone https://github.com/NvChad/starter ~/.config/nvim
		elif [[ "$installed_nvim_distro" == "lazyvim" ]]; then
			git clone https://github.com/LazyVim/starter ~/.config/nvim
		elif [[ "$installed_nvim_distro" == "mynvim" ]]; then
			git clone https://github.com/sabamdarif/mynvim.git ~/.config/nvim
		fi
		print_to_config "installed_nvim_distro"
		check_and_delete "$TERMUX_HOME/.config/nvim/.git"
	elif [[ ${installed_ide} == "all" ]]; then
		package_install_and_check "code-oss code-is-code-oss geany neovim lua51 lua-language-server stylua"
		package_install_and_check "tree-sitter-*"
		check_and_backup "$TERMUX_HOME/.config/nvim"
		if [[ "$installed_nvim_distro" == "nvchad" ]]; then
			git clone https://github.com/NvChad/starter ~/.config/nvim
		elif [[ "$installed_nvim_distro" == "lazyvim" ]]; then
			git clone https://github.com/LazyVim/starter ~/.config/nvim
		elif [[ "$installed_nvim_distro" == "mynvim" ]]; then
			git clone https://github.com/sabamdarif/mynvim.git ~/.config/nvim
		fi
		print_to_config "installed_nvim_distro"
		check_and_delete "$TERMUX_HOME/.config/nvim/.git"
	elif [[ ${installed_ide} == "skip" ]]; then
		print_msg "${C}Skipping Ide Installation..."
		echo
		sleep 2
	else
		package_install_and_check "code-oss code-is-code-oss"
	fi
}

#########################################################################
#
# Install Media Player
#
#########################################################################

function media_player_installer() {
	banner
	print_to_config "installed_media_player"
	if [[ ${installed_media_player} == "vlc" ]]; then
		package_install_and_check "vlc-qt-static"
	elif [[ ${installed_media_player} == "mpv" ]]; then
		package_install_and_check "mpv"
	elif [[ ${installed_media_player} == "all" ]]; then
		package_install_and_check "vlc-qt-static mpv"
	elif [[ ${installed_media_player} == "skip" ]]; then
		print_msg "${C}Skipping Media Player Installation..."
		echo
		sleep 2
	else
		package_install_and_check "vlc-qt-static"
	fi
}

#########################################################################
#
# Install Photo Editor
#
#########################################################################

function setup_gimp_plugins() {
	package_install_and_check "gimp-resynthesizer"
}

function photo_editor_installer() {
	banner
	print_to_config "installed_photo_editor"
	if [[ ${installed_photo_editor} == "gimp" ]]; then
		package_install_and_check "gimp"
		setup_gimp_plugins
	elif [[ ${installed_photo_editor} == "inkscape" ]]; then
		package_install_and_check "inkscape"
	elif [[ ${installed_photo_editor} == "all" ]]; then
		package_install_and_check "gimp inkscape"
		setup_gimp_plugins
	elif [[ ${installed_photo_editor} == "skip" ]]; then
		print_msg "${C}Skipping Photo Editor Installation..."
		echo
		sleep 2
	else
		package_install_and_check "gimp"
	fi
}

#########################################################################
#
# Install Software Manager
#
#########################################################################

function install_termux_desktop_appstore() {
	banner
	print_msg "${C}Setting up AppStore..."
	echo
	download_file "https://raw.githubusercontent.com/$REPO_OWNER/Termux-AppStore/refs/heads/src/appstore"
	chmod +x "appstore"
	./appstore --install v0.5.4.1
	cp "${PREFIX}/share/applications/org.sabamdarif.termux.appstore.desktop" "$TERMUX_HOME/Desktop"
	chmod +x "$TERMUX_HOME/Desktop/org.sabamdarif.termux.appstore.desktop"
}

#########################################################################
#
# Setup shell bash / zsh
#
#########################################################################

function get_shellrc_path() {
	if [[ -z "$shell_name" ]]; then
		shell_name=$(basename "$SHELL")
	fi
	if [[ "$shell_name" == "bash" ]]; then
		shell_rc_file="$TERMUX_HOME/.bashrc"
	elif [[ "$shell_name" == "zsh" ]]; then
		shell_rc_file="$TERMUX_HOME/.zshrc"
	else
		print_failed "Unable to get shellrc path"
		exit 1
	fi
}

function setup_zsh() {
	banner
	shell_name="zsh"
	print_msg "${BOLD}Configuring zsh.."
	package_install_and_check "zsh git"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/setup-zsh"
	chmod +x setup-zsh
	# shellcheck disable=SC1091
	source setup-zsh
	check_and_delete "setup-zsh"
	if [[ -f "$TERMUX_HOME/.zshrc" ]]; then
		print_success "zsh setup successfully"
	fi
	clear
	print_to_config "selected_zsh_theme_name"
}

function setup_bash() {
	banner
	shell_name="bash"
	print_msg "${BOLD}Configuring bash.."
	package_install_and_check "git"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/setup-bash"
	chmod +x setup-bash
	# shellcheck disable=SC1091
	source setup-bash
	check_and_delete "setup-bash"
	if [[ -f "$TERMUX_HOME/.bashrc" ]]; then
		print_success "bash setup successfully"
	fi
	clear
}

function setup_shell() {
	print_to_config "chosen_shell_name"
	if [[ "$chosen_shell_name" == "zsh" ]]; then
		setup_zsh
	elif [[ "$chosen_shell_name" == "bash" ]] || [[ "$chosen_shell_name" == "bash_with_ble" ]]; then
		setup_bash
	fi
	get_shellrc_path
}

function terminal_utility_setup() {
	if [[ "$terminal_utility_setup_answer" == "n" ]]; then
		banner
		print_msg "${C}Skipping Terminal Utility Setup..."
		echo
	else
		banner
		print_msg "${C}${BOLD}Configuring Terminal Utility For Termux..."
		echo
		package_install_and_check "bat eza zoxide fastfetch openssh fzf"
		if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
			package_install_and_check "nala"
		fi
		check_and_backup "$TERMUX_PREFIX/etc/motd"
		check_and_backup "$TERMUX_PREFIX/etc/motd-playstore"
		check_and_backup "$TERMUX_PREFIX/etc/motd.sh"
		download_file "$TERMUX_PREFIX/etc/motd.sh" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/motd.sh"
		if grep -q "motd.sh$" "$TERMUX_PREFIX/etc/termux-login.sh"; then
			sed -i "s|.*motd\.sh$|bash $TERMUX_PREFIX/etc/motd.sh|" "$TERMUX_PREFIX/etc/termux-login.sh"
		else
			echo "bash $TERMUX_PREFIX/etc/motd.sh" >>"$TERMUX_PREFIX/etc/termux-login.sh"
		fi
		check_and_create_directory "$TERMUX_HOME/.termux"
		check_and_backup "$TERMUX_HOME/.termux/colors.properties $TERMUX_HOME/.termux/termux.properties $TERMUX_HOME/.aliases $TERMUX_HOME/.nanorc"

		check_and_create_directory "$TERMUX_HOME/.config/fastfetch"
		download_file "$TERMUX_HOME/.config/fastfetch/config.jsonc" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/config.jsonc"
		download_file "$TERMUX_HOME/.termux/termux.properties" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termux.properties"
		download_file "$TERMUX_HOME/.aliases" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/.aliases"
		download_file "$TERMUX_HOME/.nanorc" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/.nanorc"
		download_file "$TERMUX_HOME/.termux/colors.properties" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/colors.properties"
		download_file "$TERMUX_PREFIX/bin/termux-ssh" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termux-ssh" && chmod +x "$TERMUX_PREFIX/bin/termux-ssh"
		download_file "$TERMUX_PREFIX/bin/termux-fastest-repo" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termux-fastest-repo"
		chmod +x "$TERMUX_PREFIX/bin/termux-fastest-repo"
		download_file "$TERMUX_PREFIX/bin/termux-color" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termux-color"
		chmod +x "$TERMUX_PREFIX/bin/termux-color"
		download_file "$TERMUX_PREFIX/bin/termux-nf" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/termux-nf"
		chmod +x "$TERMUX_PREFIX/bin/termux-nf"
		cp "$shell_rc_file" "${shell_rc_file}-2"
		check_and_backup "$shell_rc_file"
		mv "${shell_rc_file}-2" "${shell_rc_file}"

		cat <<-EOF >>"$TERMUX_HOME/.shell_rc_content"
			# set zoxide as cd
			eval "\$(zoxide init --cmd cd ${shell_name})"

			# FZF color scheme
			export FZF_DEFAULT_OPTS=" \
			--color=bg+:#363a4f,bg:#24273a,spinner:#f4dbd6,hl:#ed8796 \
			--color=fg:#cad3f5,header:#ed8796,info:#c6a0f6,pointer:#f4dbd6 \
			--color=marker:#b7bdf8,fg+:#cad3f5,prompt:#c6a0f6,hl+:#ed8796 \
			--color=selected-bg:#494d64 \
			--color=border:#363a4f,label:#cad3f5"
		EOF
	fi

	cat <<-EOF >>"$TERMUX_HOME/.shell_rc_content"
		# print your current termux-desktop configuration
		alias 'tdconfig'='cat "$CONFIG_FILE"'
		if [[ \$TERMUX_HOME != *termux* ]]; then
		  export DISPLAY=:$display_number
		fi
	EOF
	if [[ "$distro_add_answer" == "y" ]]; then
		cat <<-EOF >>"$TERMUX_HOME/.shell_rc_content"
			# open the folder where all the apps added by proot-distro are located
			alias 'pdapps'='cd $TERMUX_PREFIX/share/applications/pd_added && ls'
		EOF
	fi

	if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
		cat <<-'EOF' >>"$TERMUX_HOME/.shell_rc_content"
			apt_wrapper() {
			    # First check if nala is actually installed. If not fall back to the apt
			    if ! command -v nala >/dev/null 2>&1; then
			        echo "nala not found, falling back to apt."
			        command apt "$@"
			        return $?
			    fi

			    # If no argument given then run nala to print help menu
			    if [ -z "$1" ]; then
			        command nala
			        return
			    fi

			    local cmd="$1"
			    shift

			    case "$cmd" in
			    install | in | add)
			        command nala install "$@"
			        ;;
			    se* | sr | find)
			        command nala search "$@"
			        ;;
			    up | update)
			        command nala update "$@"
			        ;;
			    upg*)
			        command nala upgrade "$@"
			        ;;
			    show | info)
			        command nala show "$@"
			        ;;
			    cl*)
			        command nala clean "$@"
			        ;;
			    ap | autopurge)
			        command nala autopurge "$@"
			        ;;
			    un* | rem* | rm | del* | r)
			        command nala remove "$@"
			        ;;
			    list-up*)
			        command nala list --upgradable
			        ;;
			    *)
			        # pass the command ($cmd) along with the rest of the arguments
			        # although i don't think we need to pass $@
			        # but i still did it just to be in the safe side
			        command nala "$cmd" "$@"
			        ;;
			    esac
			}

			alias apt='apt_wrapper'
		EOF
	fi

	echo "[[ -f $TERMUX_HOME/.shell_rc_content ]] && source $TERMUX_HOME/.shell_rc_content" >>"${shell_rc_file}"

	if [[ "$terminal_utility_setup_answer" == "y" ]]; then
		echo "[[ -f $TERMUX_HOME/.aliases ]] && source $TERMUX_HOME/.aliases" >>"${shell_rc_file}"
	fi

	print_to_config "terminal_utility_setup_answer"
}

#########################################################################
#
# Setup File Manager Utility
#
#########################################################################
function install_fm_tools() {
	if [[ "$fm_tools" == "y" ]]; then
		banner
		print_msg "${BOLD}Installing File Manager Tools..."
		check_and_backup "$TERMUX_HOME/.local/share/nautilus/scripts"
		check_and_create_directory "$TERMUX_HOME/.local/share/nautilus/scripts"
		package_install_and_check "axel bzip2 cabextract cpio cups curl ffmpeg file-roller filelight go-findimagedupes ghex git gnupg gzip id3v2 imagemagick inkscape inetutils libarchive exiftool liblzma sox lrzip lz4 lzip lzop mediainfo mp3gain nmap openssl optipng p7zip pandoc perl poppler qpdf rdfind rhash squashfs-tools-ng tar tesseract texlive-bin unar unrar unzip xclip xorriso xz-utils zip zpaq zstd"
		git clone https://github.com/cfgnunes/nautilus-scripts.git
		check_and_delete "nautilus-scripts/Security\ and\ recovery/File\ carving\ (via Foremost)"
		check_and_delete "nautilus-scripts/Security\ and\ recovery/File\ carving\ (via PhotoRec)"
		cd nautilus-scripts || return 1
		bash install.sh -n
		cd .. || return 1
		check_and_delete "nautilus-scripts"
	fi
	print_to_config "fm_tools"
}

#########################################################################
#
# Setup usb auto bookmarks utility
#
#########################################################################

function add_usb_auto_mount() {
	print_msg "Adding USB auto filemanager bookmarks utility..."
	download_file "$TERMUX_PREFIX/bin/usb-bookmarks" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/usb-bookmarks"
	chmod +x "$TERMUX_PREFIX/bin/usb-bookmarks"
	check_and_create_directory "$TERMUX_HOME/.config/autostart"
	cat <<-EOF >"$TERMUX_HOME/.config/autostart/usb-bookmarks.desktop"
		[Desktop Entry]
		Type=Application
		Version=1.0
		Name=USB Bookmarks Sync
		Comment=Keep File Manager bookmarks in sync with mounted USB volumes
		Exec=usb-bookmarks --watch
		X-GNOME-Autostart-enabled=true
		OnlyShowIn=XFCE;
		NoDisplay=true
	EOF
}

#########################################################################
#
# Install Fonts
#
#########################################################################

function setup_fonts() {
	banner
	print_msg "${BOLD}Installing ${sel_base_name} Nerd Font..."

	package_install_and_check "nerdfix fontconfig-utils"
	check_and_create_directory "$TERMUX_HOME/.termux"
	check_and_create_directory "$TERMUX_HOME/.fonts"
	check_and_backup "$TERMUX_HOME/.termux/font.ttf"

	if [[ -z "$latest_nf_version" ]]; then
		latest_nf_version=$(get_latest_release "ryanoasis" "nerd-fonts")
	fi

	if [[ -z "$sel_base_name" ]]; then
		sel_base_name="0xProto"
	fi
	print_to_config "sel_base_name"

	download_and_extract "https://github.com/ryanoasis/nerd-fonts/releases/download/${latest_nf_version}/${sel_base_name}.tar.xz" "$TERMUX_HOME/.fonts"
	nerd_font_file=$(find "$TERMUX_HOME/.fonts" -type f \( -iname "${sel_base_name}*NerdFont-Regular.ttf" -o -iname "${sel_base_name}*NerdFont-Regular.otf" \) | head -n1)

	if [[ -z "$nerd_font_file" ]]; then
		nerd_font_file=$(find "$TERMUX_HOME/.fonts" -type f -iname "*NerdFont*" | head -n1)
	fi

	check_and_delete "$TERMUX_HOME/.fonts/README.md $TERMUX_HOME/.fonts/LICENSE"

	if [[ -n "$nerd_font_file" ]]; then
		cp "$nerd_font_file" "$TERMUX_HOME/.termux/font.ttf"
		fc-cache -f
	else
		print_failed "Could not locate a NerdFont-Regular file for ${sel_base_name}."
		exit 1
	fi
}

#########################################################################
#
# Install Wine
#
#########################################################################

function run_wine_shortcut_script() {
	print_success "Adding wine desktop shortcuts..."
	download_file "add-wine-shortcut" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/other/add-wine-shortcut"
	chmod +x "add-wine-shortcut"
	# shellcheck disable=SC1091
	source add-wine-shortcut
	check_and_delete "add-wine-shortcut"
}

function setup_wine() {
	banner
	print_to_config "installed_wine"
	if [[ "$installed_wine" == "stock" ]]; then
		print_msg "${BOLD}Installing Wine Natively In Termux"
		echo
		package_install_and_check "wine-stable"
		run_wine_shortcut_script
	elif [[ "$installed_wine" == "mobox" ]]; then
		print_msg "${BOLD}Addind Mobox Launch Option To Termux"
		echo
		print_msg "${C}${BOLD}After the installation finishes, make sure to install Mobox using their official instructions"
		echo
		print_msg "${BOLD}Mobox:- ${C}https://github.com/olegos2/mobox"
		echo
		sleep 4
		download_file "$TERMUX_PREFIX/bin/wine" "https://raw.githubusercontent.com/LinuxDroidMaster/Termux-Desktops/main/scripts/termux_native/mobox_run.sh"
		chmod +x "$TERMUX_PREFIX/bin/wine"
		cp "$TERMUX_PREFIX/share/applications/wine-explorer.desktop" "$TERMUX_HOME/Desktop/MoboxExplorer.desktop"
		run_wine_shortcut_script
	elif [[ "$installed_wine" == "wine_hangover" ]]; then
		package_install_and_check "hangover-wine"
		run_wine_shortcut_script
		if [[ ! -f "$TERMUX_PREFIX/bin/wine" ]]; then
			ln -s "$TERMUX_PREFIX/bin/hangover-wine" "$TERMUX_PREFIX/bin/wine"
		fi
	elif [[ "$installed_wine" == "skip" ]]; then
		print_msg "${C}Skipping wine Installation..."
	else
		print_msg "Installing Wine Natively In Termux"
		echo
		package_install_and_check "wine-stable"
		run_wine_shortcut_script
	fi
}

#########################################################################
#
# Add Autostart
#
#########################################################################

function add_vnc_autostart() {
	print_msg "${BOLD}Adding vnc to autostart"
	if grep -q "^vncstart" "$shell_rc_file"; then
		print_msg "Termux:X11 start already exist"
	else
		cat <<-EOF >>"$shell_rc_file"
			# Start Vnc
			if ! pgrep Xvnc > /dev/null; then
			echo "${G}Starting Vnc...${NC}"
			vncstart
			fi
		EOF
	fi
}

function add_tx11_autostart() {
	print_msg "${BOLD}Adding Termux:x11 to autostart"
	if grep -q "^tx11start" "$shell_rc_file"; then
		print_msg "Termux:X11 start already exist"
	else
		cat <<-EOF >>"$shell_rc_file"
			# Start Termux:X11
			termux_x11_pid=\$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
			if [ -z "\$termux_x11_pid" ]; then
			echo "${G}Starting Termux:x11...${NC}"
			tx11start
			fi
		EOF
	fi
}

function add_to_autostart() {
	print_to_config "de_on_startup"
	if [[ "$de_on_startup" == "y" ]]; then
		if [[ "$default_gui_mode" == "vnc" ]]; then
			add_vnc_autostart
		elif [[ "$default_gui_mode" == "termux_x11" ]] || [[ "$gui_mode" == "termux_x11" ]]; then
			add_tx11_autostart
		fi
		if [[ "$gui_mode" == "both" ]]; then
			print_to_config "default_gui_mode"
		fi
	fi
}

#########################################################################
#
# Finish | Notes
#
#########################################################################
function cleanup_cache() {
	banner
	print_msg "Cleaning up the cache..."
	if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
		pacman -Scc --noconfirm
	else
		apt clean all
	fi
}

function add_common_function() {
	check_and_delete "$TERMUX_PREFIX/etc/termux-desktop/common_functions"
	cat <<-EOF >"$TERMUX_PREFIX/etc/termux-desktop/common_functions"
		#!/data/data/com.termux/files/usr/bin/bash

		# Repository URLs
		readonly REPO_OWNER="$REPO_OWNER"
		readonly REPO_NAME="$REPO_NAME"
		readonly REPO_BRANCH_MAIN="$REPO_BRANCH_MAIN"
		readonly REPO_SETUP_FILE_BRANCH="$REPO_SETUP_FILE_BRANCH"
		readonly REPO_SETUP_FILES_FOLDER="$REPO_SETUP_FILES_FOLDER"
		readonly REPO_RAW_URL="$REPO_RAW_URL"
		readonly TERMUX_HOME="$TERMUX_HOME"
		readonly TERMUX_PREFIX="$TERMUX_PREFIX"
		# Retry configuration
		readonly MAX_DOWNLOAD_RETRIES="$MAX_DOWNLOAD_RETRIES"
		readonly MAX_INSTALL_RETRIES="$MAX_INSTALL_RETRIES"
		readonly DOWNLOAD_TIMEOUT="$DOWNLOAD_TIMEOUT"

		#########################################################################
		#
		# Initial Values
		#
		#########################################################################
		readonly TERMUX_DESKTOP_PATH="$TERMUX_DESKTOP_PATH"
		readonly CONFIG_FILE="$CONFIG_FILE"
		readonly LOG_FILE="$LOG_FILE"
		LITE_MODE="$LITE_MODE"
		#########################################################################
		#
		# Color Setup
		#
		#########################################################################
		# shellcheck disable=SC2154
		R="$R"
		G="$G"
		Y="$Y"
		B="$B"
		C="$C"
		NC="$NC"
		BOLD="$BOLD"
	EOF
	typeset -f check_termux log_debug print_success print_failed print_warn print_msg wait_for_keypress check_and_create_directory check_and_delete check_and_backup download_file check_and_restore detect_package_manager package_install_and_check package_check_and_remove get_file_name_number extract_zip_with_progress extract_archive download_and_extract count_subfolders confirmation_y_or_n get_latest_release install_font_for_style select_an_option read_conf print_to_config >>"$TERMUX_PREFIX/etc/termux-desktop/common_functions"
	chmod +x "$TERMUX_PREFIX/etc/termux-desktop/common_functions"
}

function notes() {
	banner
	print_msg "Installation Successfull..."
	echo
	sleep 2
	print_msg "${C}${BOLD}Now Restart Termux ${G}(Must)"
	echo
	print_msg "${C}${BOLD}Some basic commands:-${G}(Must know)"
	echo
	print_msg "tx11start        to start the gui with termux:x11"
	echo
	print_msg "tx11stop         to stop the gui with termux:x11"
	echo
	print_msg "tx11stop -f      to force stop the gui with termux:x11"
	echo
	if [[ "$gui_mode" == "both" ]]; then
		print_msg "vncstart         to start the gui with vnc"
		echo
		print_msg "vncstop          to stop the gui with vnc"
		echo
	fi
	if [[ "$distro_add_answer" == "y" ]]; then
		print_msg "${C}run:- $selected_distro, to login into $selected_distro"
	fi
	echo
	print_msg "${C}${BOLD}See Uses Section in github to know how to use it"
	echo
	print_msg "${C}URL:- ${B}https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/main/README.md#5-usage-instructions"
	echo
	if [[ "$distro_add_answer" == "y" ]]; then
		print_msg "${C}${BOLD}See how to use Linux distro container"
		echo
		print_msg "${C}URL:- ${B}https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/main/docs/proot-container.md"
	fi
}

#########################################################################
#
# Remove
#
#########################################################################

function remove_desktop_environments() {
	if [[ "$de_name" == "xfce" ]]; then
		package_check_and_remove "xfce4 xfce4-goodies xfce4-pulseaudio-plugin xfce4-battery-plugin xfce4-docklike-plugin xfce4-notifyd-static kvantum gtk2-engines-murrine"
	elif [[ "$de_name" == "lxqt" ]]; then
		package_check_and_remove "lxqt xorg-xsetroot papirus-icon-theme xwayland kvantum"
	elif [[ "$de_name" == "openbox" ]]; then
		package_check_and_remove "openbox polybar xorg-xsetroot lxappearance wmctrl feh xwayland kvantum thunar firefox mpd rofi bmon xcompmgr xfce4-settings gedit"
	elif [[ "$de_name" == "mate" ]]; then
		package_check_and_remove "mate*"
		package_check_and_remove "marco mousepad xfce4-taskmanager lximage-qt"
	elif [[ "$de_name" == "i3wm" ]]; then
		package_check_and_remove "i3 rofi mpv polybar xcompmgr nitrogen"
	elif [[ "$de_name" == "dwm" ]]; then
		package_check_and_remove "dwm"
	elif [[ "$de_name" == "bspwm" ]]; then
		package_check_and_remove "bspwm lxappearance xorg-xsetroot rofi feh nemo st"
	elif [[ "$de_name" == "wmaker" ]]; then
		package_check_and_remove "wmaker lxappearance nemo xterm"
	elif [[ "$de_name" == "awesome" ]]; then
		package_check_and_remove "awesome"
	elif [[ "$de_name" == "fluxbox" ]]; then
		package_check_and_remove "fluxbox xorg-xsetroot xorg-xprop lxappearance wmctrl feh firefox rofi bmon xcompmgr gtk3 gedit xmllint"
	elif [[ "$de_name" == "gnome" ]]; then
		package_check_and_remove "gnome*"
		package_check_and_remove "thunar xfce4-terminal"
	elif [[ "$de_name" == "cinnamon" ]]; then
		package_check_and_remove "cinnamon nemo gnome-terminal gnome-screenshot eog"
	fi
}

function remove_termux_desktop() {
	if [[ ! -e "$CONFIG_FILE" ]]; then
		print_msg "${C}${BOLD}Please Install Termux Desktop First"
		exit 1
	else
		banner
		print_msg "${R}${BOLD} Remove Termux Desktop"
		echo ""
		confirmation_y_or_n "Are You Sure You Want To Remove Termux Desktop Completely" ask_remove
		# shellcheck disable=SC2154
		if [[ "$ask_remove" == "n" ]]; then
			print_msg "${BOLD}Canceling..."
			exit 0
		else
			print_msg "${R}${BOLD}Removeing Termux Desktop"
			sleep 3
			read_conf
			#remove basic packages
			package_check_and_remove "pulseaudio x11-repo tur-repo"
			#remove desktop related packages
			remove_desktop_environments
			package_check_and_remove "kvantum xwayland pulseaudio file-roller pavucontrol gnome-font-viewer evince galculator libwayland-protocols xorg-xrdb"
			#remove zsh
			if [[ "$chosen_shell_name" == "zsh" ]]; then
				package_check_and_remove "zsh"
				check_and_delete "$TERMUX_HOME/.zsh_history $TERMUX_HOME/.zshrc"
			fi
			#remove terminal utility
			if [[ "$terminal_utility_setup_answer" == "y" ]]; then
				check_and_delete "$TERMUX_PREFIX/etc/motd.sh $TERMUX_HOME/.termux $TERMUX_HOME/.fonts/font.ttf $TERMUX_HOME/.termux/colors.properties"
				check_and_restore "$TERMUX_PREFIX/etc/motd"
				check_and_restore "$TERMUX_PREFIX/etc/motd-playstore"
				check_and_restore "$TERMUX_PREFIX/etc/motd.sh"
				check_and_restore "$TERMUX_HOME/.termux/colors.properties"
				if grep -q "motd.sh$" "$TERMUX_PREFIX/etc/termux-login.sh"; then
					sed -i "s|.*motd\.sh$|# |" "$TERMUX_PREFIX/etc/termux-login.sh"
				fi
				package_check_and_remove "nerdfix fontconfig-utils bat eza"
			fi
			#remove browser
			if [[ "$installed_browser" == "firefox" ]]; then
				package_check_and_remove "firefox"
			elif [[ "$installed_browser" == "chromium" ]]; then
				package_check_and_remove "chromium"
			elif [[ "$installed_browser" == "all" ]]; then
				package_check_and_remove "firefox chromium"
			fi
			#remove ide
			if [[ "$installed_ide" == "code" ]]; then
				package_check_and_remove "code-oss code-is-code-oss"
			elif [[ "$installed_ide" == "neovim" ]]; then
				package_check_and_remove "neovim lua51 lua-language-server stylua  tree-sitter-lua"
			elif [[ "$installed_ide" == "geany" ]]; then
				package_check_and_remove "geany"
			elif [[ "$installed_ide" == "all" ]]; then
				package_check_and_remove "code-oss code-is-code-oss geany neovim lua51 lua-language-server stylua  tree-sitter-lua"
			fi
			#remove media player
			if [[ "$installed_media_player" == "vlc" ]]; then
				package_check_and_remove "vlc-qt-static"
			elif [[ "$installed_media_player" == "audacious" ]]; then
				package_check_and_remove "audacious"
			elif [[ "$installed_media_player" == "both" ]]; then
				package_check_and_remove "vlc-qt-static audacious"
			fi
			#remove photo editor
			if [[ "$installed_photo_editor" == "gimp" ]]; then
				package_check_and_remove "gimp"
			elif [[ "$installed_photo_editor" == "audacious" ]]; then
				package_check_and_remove "audacious"
			elif [[ "$installed_photo_editor" == "both" ]]; then
				package_check_and_remove "gimp audacious"
			fi
			#remove wine
			if [[ "$installed_wine" == "stock" ]]; then
				package_check_and_remove "wine"
			elif [[ "$installed_wine" == "mobox" ]]; then
				print_msg "${C}${BOLD}Make Sure To Uninstall Mobox Using Their Instruction"
				check_and_delete "$TERMUX_HOME/Desktop/MoboxExplorer.desktop"
				sleep 4
			elif [[ "$installed_wine" == "wine_hangover" ]]; then
				package_check_and_remove "hangover-wine"
			fi
			check_and_delete "$TERMUX_PREFIX/bin/wine $TERMUX_PREFIX/share/applications/wine-*"
			#remove styles
			if [[ "$style_answer" == "5" ]]; then
				package_check_and_remove "eww"
			fi
			#Remove folders and other files
			check_and_delete "$TERMUX_PREFIX/share/backgrounds $themes_folder $icons_folder $TERMUX_PREFIX/etc/termux-desktop"
			check_and_delete "$TERMUX_HOME/.config/$the_config_dir"
			check_and_delete "$TERMUX_HOME/Desktop $TERMUX_HOME/Downloads $TERMUX_HOME/Videos $TERMUX_HOME/Pictures $TERMUX_HOME/Music"
			#remove hw packages
			package_check_and_remove "mesa-zink virglrenderer-mesa-zink vulkan-loader-android angle-android virglrenderer-android mesa-vulkan-icd-freedreno mesa-vulkan-icd-wrapper mesa-zink"
			#remove distro container
			if [[ "$distro_add_answer" == "y" ]]; then
				proot-distro remove "$selected_distro"
				proot-distro clear-cache
				package_check_and_remove "proot-distro"
				check_and_delete "$TERMUX_PREFIX/bin/$selected_distro $TERMUX_PREFIX/bin/pdrun"
			fi
			#remove vnc and termux x11
			check_and_delete "$TERMUX_PREFIX/bin/gui"
			if [[ "$gui_mode" == "termux_x11" ]]; then
				package_check_and_remove "termux-x11-nightly xorg-xhost"
				check_and_delete "$TERMUX_PREFIX/bin/tx11start $TERMUX_PREFIX/bin/tx11stop"
			elif [[ "$gui_mode" == "both" ]]; then
				package_check_and_remove "termux-x11-nightly tigervnc xorg-xhost"
				check_and_delete "$TERMUX_PREFIX/bin/tx11start $TERMUX_PREFIX/bin/tx11stop $TERMUX_HOME/.vnc/xstartup $TERMUX_PREFIX/bin/vncstart $TERMUX_PREFIX/bin/vncstop $TERMUX_PREFIX/bin/gui $TERMUX_PREFIX/bin/tx11start $TERMUX_PREFIX/bin/tx11stop"
				# shellcheck disable=SC2164
				cd "$TERMUX_PREFIX/share/zsh/site-functions"
				check_and_delete "_add2menu _distro _setup-termux-desktop _tx11start _tx11stop _vncstart _vncstop"
				# shellcheck disable=SC2164
				cd "$TERMUX_PREFIX/share/bash-completion/completions"
				check_and_delete "add2menu distro setup-termux-desktop tx11start tx11stop vncstart vncstop"
				# shellcheck disable=SC2164
				cd "$TERMUX_HOME"
				# remove appstore
				package_check_and_remove "aria2 python python3 cloneit"
				check_and_delete "${PREFIX}/opt/appstore"
				check_and_delete "${PREFIX}/share/applications/org.sabamdarif.termux.appstore.desktop"
			fi
			check_and_delete "$TERMUX_PREFIX/etc/termux-desktop $TERMUX_PREFIX/bin/setup-termux-desktop"
			clear
			print_msg "${BOLD}Everything remove successfully"
		fi
	fi
}

#########################################################################
#
# Change Style
#
#########################################################################

function gui_check_up() {
	termux_x11_pid=$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
	vnc_server_pid=$(pgrep -f "vncserver")
	de_pid=$(pgrep -f "$de_startup")
	if [[ -n "$termux_x11_pid" ]] || [[ -n "$de_pid" ]] || [[ -n "$vnc_server_pid" ]] >/dev/null 2>&1; then
		echo "${G}Please Stop The Gui Desktop Server First${NC}"
		exit 0
	fi
}

function change_style() {
	if [[ ! -e "$CONFIG_FILE" ]]; then
		echo -e "${C} It look like you haven't install the desktop yet\n Please install the desktop first${NC}"
		exit 1
	else
		read_conf
		gui_check_up
		banner
		download_file "${current_path}/styles.md" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/docs/${de_name}_styles.md"
		style_name=$(grep -oP "^## $style_answer\..+?(?=(\n## \d+\.|\Z))" "${current_path}/styles.md" | sed -e "s/^## $style_answer\. //" -e "s/:$//" -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
		check_and_delete "${current_path}/styles.md"
		print_msg "Your currently installed style is ${C}${BOLD}$style_name"
		echo
		sleep 2
		unset style_name
		questions_theme_select
		rm -rf ~/.cache/sessions/*
		setup_config
		banner
		print_msg "Style changed successfully"
		echo
		print_msg "Your currently installed style is ${C}${BOLD}$style_name"
	fi
}

#########################################################################
#
# Change Hardware Acceleration
#
#########################################################################

function do_hw_changes() {
	try_to_autodetect_gpu
	setup_device_gpu_model
	hw_questions
	update_sys
	# it's needed because the turnip setup uses a function that is
	# created in the distro-container-setup script
	get_distro_container_source
	# Source the script
	# shellcheck disable=SC1091
	source "${current_path}/distro-container-setup"
	set_distro_paths
	hw_config
	if [[ "$gui_mode" == "termux_x11" ]]; then
		setup_tx11start_cmd
		some_fixes
	elif [[ "$gui_mode" == "both" ]]; then
		setup_tx11start_cmd
		setup_vncstart_cmd
		some_fixes
	fi
	if [[ "$distro_add_answer" == "y" ]]; then
		get_distro_container_source
		# shellcheck disable=SC1091
		source "${current_path}/distro-container-setup"

		# set the required variables for pdrun
		if [[ "$selected_distro_type" == "chroot" ]]; then
			termux_home_link=" "
		else
			# shellcheck disable=SC2034
			termux_home_link="--termux-home"
		fi
		final_user_name="$user_name"

		distro_app_launch_setup
		check_and_delete "${current_path}/distro-container-setup"
	fi
}

function change_hw() {
	# Check if the configuration file exists
	if [[ ! -e "$CONFIG_FILE" ]]; then
		print_warn "${C}It looks like you haven't installed the desktop yee. Please install the desktop first"
		exit 1
	else
		read_conf
		local old_hw_option
		old_hw_option="${termux_hw_answer}"
		if [[ "$enable_hw_acc" == "y" ]]; then
			banner
			print_msg "Your current hardware acceleration api for Termux is: ${C}${BOLD}${termux_hw_answer}"
			if [[ "$distro_add_answer" == "y" ]]; then
				print_msg "Your current hardware acceleration api for $selected_distro is: ${C}${BOLD}${pd_hw_answer}"
			fi
			confirmation_y_or_n "Do you want to change hardware acceleration api" confirmation_change_hardware_acceleration
			# shellcheck disable=SC2154
			if [[ "$confirmation_change_hardware_acceleration" == "y" ]]; then
				do_hw_changes
				read_conf
				if [[ "$old_hw_option" != "$termux_hw_answer" ]]; then
					print_success "${BOLD}Hardware acceleration method successfully changed to ${termux_hw_answer}"
					exit 0
				elif [[ "$old_hw_option" == "$termux_hw_answer" ]]; then
					print_success "${BOLD}Hardware acceleration method is still on ${termux_hw_answer}"
					exit 0
				else
					print_failed "Something went wrong during the hardware acceleration process..."
					exit 1
				fi
			fi
		elif [[ "$enable_hw_acc" == "n" ]]; then
			print_msg "This option can only be used if have Hardware Acceleration enabled"
			confirmation_y_or_n "Do you want to enable Hardware Acceleration" confirmation_want_to_enable_hw
			# shellcheck disable=SC2154
			if [[ "$confirmation_want_to_enable_hw" == "y" ]]; then
				enable_hw_acc="y"
				do_hw_changes
				read_conf
				if [[ "$enable_hw_acc" == "y" ]]; then
					print_success "${BOLD}Successfully enable hardware acceleration"
				else
					print_failed "Some issue occurred during the hardware acceleration change process..."
				fi
			elif [[ "$confirmation_want_to_enable_hw" == "n" ]]; then
				print_msg "Keeping Hardware Acceleration disabled"
				exit 0
			fi
		fi
	fi
}

#########################################################################
#
# Change Distro
#
#########################################################################

function add_distro_again() {
	print_msg "${BOLD}Do you want to add a Linux distro container"
	echo
	print_msg "It will help you to install those app which are not avilable in termux"
	echo
	print_msg "You can launch those installed apps from termux like other apps"
	echo
	confirmation_y_or_n "Do you want to continue" distro_add_answer
	if [[ "$distro_add_answer" == "y" ]]; then
		print_to_config "distro_add_answer"
		distro_questions
		if [[ "$enable_hw_acc" == "y" ]]; then
			distro_hw_questions
			# call setup_hw_environment_variables from hw-acceleration setup script
			# this is needed for pdrun command
			get_hw_acceleration_source
			# shellcheck disable=SC1091
			source "${current_path}/enable-hw-acceleration"
			setup_hw_environment_variables
			check_and_delete "${current_path}/enable-hw-acceleration"
		fi
		distro_container_setup
	fi
}

function change_distro() {
	if [[ ! -e "$CONFIG_FILE" ]]; then
		echo -e "${C} It look like you haven't install the desktop yet\n Please install the desktop first${NC}"
		exit 1
	else
		read_conf
		banner
		if [[ "$distro_add_answer" == "y" ]]; then
			local old_distro
			old_distro="${selected_distro}"
			if [[ -z "$selected_distro_type" ]]; then
				if command -v chroot-distro >/dev/null 2>&1; then
					selected_distro_type=chroot
				else
					selected_distro_type=proot
				fi
			fi

			if [[ "$selected_distro_type" == "chroot" ]]; then
				if ! timeout 3s su -c "ls /data/local/chroot-distro/installed-rootfs/$selected_distro" >/dev/null 2>&1; then
					print_failed "${selected_distro} isn't installed"
					add_distro_again
					exit 0
				fi
			else
				if [[ ! -d "$TERMUX_PREFIX/var/lib/proot-distro/installed-rootfs/$selected_distro" ]]; then
					print_failed "${selected_distro} isn't installed"
					add_distro_again
					exit 0
				fi
			fi

			print_msg "Your currently installed distro is: ${C}${BOLD}${selected_distro}"
			echo
			print_msg "${R}Changing distro will delete all the data from your previous distro"
			echo
			confirmation_y_or_n "Do you want to continue" distro_change_confirmation
			# shellcheck disable=SC2154
			if [[ "$distro_change_confirmation" == "y" ]]; then
				choose_distro
				print_msg "Removing $selected_distro and it's data"
				"${selected_distro_type}"-distro remove "${old_distro}"
				check_and_delete "$TERMUX_PREFIX/share/applications/pd_added"
				check_and_delete "$TERMUX_PREFIX/share/bash-completion/completions/${old_distro}"
				check_and_delete "$TERMUX_PREFIX/share/zsh/site-functions/_${old_distro}"
				check_and_delete "$TERMUX_PREFIX/bin/$selected_distro"
				get_hw_acceleration_source
				# shellcheck disable=SC1091
				source "${current_path}/enable-hw-acceleration"
				setup_hw_environment_variables
				check_and_delete "${current_path}/enable-hw-acceleration"
				if [[ "$pd_audio_config_answer" == "y" ]]; then
					rm "$TERMUX_HOME/.${selected_distro}-sound-access"
				fi
				echo
				distro_container_setup
			else
				print_msg "Canceling distro change process..."
				sleep 2
				exit 0
			fi
		else
			print_msg "It look like you haven't install any distro yet"
			echo
			add_distro_again
		fi
	fi
}

#########################################################################
#
# Change Autostart
#
#########################################################################

function change_autostart() {
	read_conf
	get_shellrc_path
	if [[ "$de_on_startup" == "y" ]]; then
		confirmation_y_or_n "You are sure you want to change auto" confirmation_change_auto_start
		# shellcheck disable=SC2154
		if [[ "$confirmation_change_auto_start" == "y" ]]; then
			if grep -q "^vncstart" "$shell_rc_file"; then
				sed -i '/# Start Vnc/,/fi/d' "$shell_rc_file"
				print_to_config "de_on_startup" "n"
			fi
			if grep -q "^tx11start" "$shell_rc_file"; then
				sed -i '/# Start Termux:X11/,/fi/d' "$shell_rc_file"
				print_to_config "de_on_startup" "n"
			fi
			print_msg "Auto start disabled"
		else
			print_msg "Keeping auto start enabled"
		fi
	elif [[ "$de_on_startup" == "n" ]]; then
		confirmation_y_or_n "You haven't have auto start enable, do you want to enable it" confirmation_enable_auto_start
		# shellcheck disable=SC2154
		if [[ "$confirmation_enable_auto_start" == "y" ]]; then
			if [[ "$gui_mode" == "both" ]]; then
				print_msg "You chose both vnc and termux:x11 to access gui mode"
				echo
				print_msg "Which will be your default"
				echo
				echo "${Y}1. Termux:x11${NC}"
				echo
				echo "${Y}2. Vnc${NC}"
				echo
				select_an_option 2 1 autostart_gui_mode_num
				if [[ "$autostart_gui_mode_num" == "1" ]]; then
					default_gui_mode="termux_x11"
				elif [[ "$autostart_gui_mode_num" == "2" ]]; then
					default_gui_mode="vnc"
				fi
			fi
			de_on_startup=y
			print_to_config "de_on_startup"
			add_to_autostart
		else
			print_msg "Keeping auto start disabled"
		fi
	fi
}

#########################################################################
#
# Change Display Port
#
#########################################################################

# change the Display Port/Display Number where it will show the output
function change_display() {
	read_conf
	gui_check_up
	# shellcheck disable=SC2154
	if [[ "$gui_mode" == "termux_x11" ]] || [[ "$gui_mode" == "both" ]]; then
		print_msg "${BOLD}Your Current Display Port: ${display_number}"
		echo
		confirmation_y_or_n "Do you want to change the display port" change_display_port
		if [[ "$change_display_port" == "y" ]]; then
			while true; do
				read -r -p "${R}[${C}-${R}]${Y}${BOLD} Type the Display Port number: ${NC}" display_number
				if [[ "$display_number" =~ ^[0-9]+$ ]]; then
					break
				else
					print_warn "${R}Please enter a valid number between 0-9"
				fi
			done
			# Get the hardware acceleration source
			get_hw_acceleration_source

			# Source the script
			# shellcheck disable=SC1091
			source "${current_path}/enable-hw-acceleration"
			setup_hw_environment_variables
			setup_gpu_specific_environment_variables
			setup_tx11start_cmd
			print_to_config "display_number"
			sed -i "s|DISPLAY=:[0-9]*|DISPLAY=:$display_number|" "${PREFIX}/bin/$selected_distro"
			log_debug "Type the Display Port number: $display_number"
		fi
	else
		print_msg "Changing display port only supported in Termux:x11"
	fi
}

#########################################################################
#
# Change Desktop Environment / window manager
#
#########################################################################

function change_de() {
	read_conf
	gui_check_up
	print_msg "Your currently installed environments is: ${C}${BOLD}${de_name}"
	echo
	print_warn "${R}Changing environment will delete all you previous configuration for that environment"
	echo
	confirmation_y_or_n "Do you want to continue" de_change_confirmation
	# shellcheck disable=SC2154
	if [[ "$de_change_confirmation" == "y" ]]; then
		old_de_name="$de_name"
		ask_to_chose_de
		update_sys
		install_required_packages
		install_desktop
		if [[ "$style_answer" == "0" ]]; then
			banner
			print_msg "${BOLD}Configuring Stock $de_name Style..."
			echo
			print_to_config "style_answer"
			ext_setup_for_stock
		else
			setup_config
		fi
		if [[ "$enable_hw_acc" == "y" ]]; then
			# it's needed because the turnip setup uses a function that is
			# created in the distro-container-setup script
			get_distro_container_source
			# Source the script
			# shellcheck disable=SC1091
			source "${current_path}/distro-container-setup"
			set_distro_paths
			# executing the hw_config here because while removeing the installed
			# desktop environment if somehow any driver get removed
			# then it will setup them again
			hw_config
		fi
		gui_launcher
		some_fixes
		print_msg "Removeing old $old_de_name environment"
		de_name="$old_de_name"
		remove_desktop_environments
		unset de_name
		read_conf
		check_desktop_process
		add_to_autostart
		echo " "
		print_msg "Your current environment is $de_name"
	fi

}

#########################################################################
#
# Reinstall themes
#
#########################################################################

function reinstall_themes() {
	read_conf
	gui_check_up
	if [[ "$style_answer" == "0" ]]; then
		print_msg "You chose stock style there is nothing to reinstall..."
		exit
	fi
	tmp_themes_folder="$TERMUX_PREFIX/tmp/themes"
	check_and_create_directory "$tmp_themes_folder"
	print_msg "Reinstalling Themes..."
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/theme.tar.gz" "$tmp_themes_folder"
	local theme_names
	theme_names=$(ls "$tmp_themes_folder")
	local theme_name
	for theme_name in $theme_names; do
		check_and_delete "$themes_folder/$theme_name"
		mv "$tmp_themes_folder/$theme_name" "$themes_folder/"
	done
	print_msg "${BOLD}Themes reinstall successfully"
}

#########################################################################
#
# Reinstall icons
#
#########################################################################

function reinstall_icons() {
	read_conf
	gui_check_up
	if [[ "$style_answer" == "0" ]]; then
		print_msg "You chose stock style there is nothing to reinstall..."
		exit
	fi
	tmp_icons_folder="$TERMUX_PREFIX/tmp/icons"
	check_and_create_directory "$tmp_icons_folder"
	package_install_and_check "gdk-pixbuf"
	print_msg "Reinstalling Icons..."
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/icon.tar.gz" "$tmp_icons_folder"
	local icon_themes_names
	icon_themes_names=$(ls "$tmp_icons_folder")
	local icon_theme
	for icon_theme in $icon_themes_names; do
		check_and_delete "$icons_folder/$icon_theme"
		mv "$tmp_icons_folder/$icon_theme" "$icons_folder/"
		print_msg "Creating icon cache..."
		gtk-update-icon-cache -f -t "$icons_folder/$icons_theme"
		gtk-update-icon-cache -f -t "$TERMUX_PREFIX/share/icons/$icons_theme"
	done
	print_msg "${BOLD}Icons reinstall successfully"
}

#########################################################################
#
# Reinstall config
#
#########################################################################

function reinstall_config() {
	read_conf
	gui_check_up
	if [[ "$style_answer" == "0" ]]; then
		print_msg "You chose stock style there is nothing to reinstall..."
		exit
	fi
	tmp_config_folder="$TERMUX_PREFIX/tmp/config"
	check_and_create_directory "$tmp_config_folder"
	print_msg "Reinstalling Config..."
	download_and_extract "$REPO_RAW_URL/refs/heads/$REPO_SETUP_FILE_BRANCH/$REPO_SETUP_FILES_FOLDER/${de_name}/look_${style_answer}/config.tar.gz" "$tmp_config_folder"
	local dot_config_file_names
	dot_config_file_names=$(ls "$tmp_config_folder")
	local dot_config_file
	for dot_config_file in $dot_config_file_names; do
		check_and_delete "$TERMUX_HOME/.config/$dot_config_file"
		mv "$tmp_config_folder/$dot_config_file" "$TERMUX_HOME/.config/"
	done
	print_msg "${BOLD}Config reinstall successfully"
}

#########################################################################
#
# Some Fixes | Finishing Tasks
#
#########################################################################

function add_auto_completion() {
	banner
	print_msg "Adding auto completions..."
	check_and_create_directory "$TERMUX_PREFIX/share/zsh/site-functions"
	# shellcheck disable=SC2164
	cd "$TERMUX_PREFIX/share/zsh/site-functions"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_setup-termux-desktop"
	if [[ "$gui_mode" == "both" ]]; then
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_vncstart"
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_vncstop"
	fi
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_tx11start"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_tx11stop"
	if [[ "$distro_add_answer" == "y" ]]; then
		download_file "_${selected_distro}" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_distro"
		sed -i "s/distro/${selected_distro}/g" "_${selected_distro}"
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/zsh/_add2menu"
	fi
	check_and_create_directory "$TERMUX_PREFIX/share/bash-completion/completions"
	# shellcheck disable=SC2164
	cd "$TERMUX_PREFIX/share/bash-completion/completions"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/setup-termux-desktop"
	if [[ "$gui_mode" == "both" ]]; then
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/vncstart"
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/vncstop"
	fi
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/tx11start"
	download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/tx11stop"
	if [[ "$distro_add_answer" == "y" ]]; then
		download_file "${selected_distro}" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/distro"
		sed -i "s/distro/${selected_distro}/g" "${selected_distro}"
		download_file "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/completion/bash/add2menu"
	fi
	cd "$TERMUX_HOME" || return 1
}

function disable_vblank_mode() {
	if [[ "$de_name" == "xfce" ]]; then
		sed -i 's|<property name="vblank_mode" type="string" value="auto"/>|<property name="vblank_mode" type="string" value="off"/>|' "$TERMUX_HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml"
	fi
}

function some_fixes() {

	# samsung oneui-6 audio fixes
	local device_brand_name
	device_brand_name=$(getprop ro.product.brand | cut -d ' ' -f 1)
	if [[ $device_brand_name == samsung* && $ANDROID_VERSION -ge 14 ]]; then
		package_install_and_check "libandroid-stub"
		# if [[ -e "/system/lib64/libskcodec.so" ]]; then
		#     grep -q 'export LD_PRELOAD=/system/lib64/libskcodec.so' "$shell_rc_file" || echo 'export LD_PRELOAD=/system/lib64/libskcodec.so' >>"$shell_rc_file"
		# fi
	fi
	# fix blank export in tx11start
	sed -i '/^export\s*$/d' "$TERMUX_PREFIX/bin/tx11start"
	# tx11start and vncstart
	if [[ "$termux_hw_answer" == "mesa_freedreno" ]] || [[ "$termux_hw_answer" == "mesa_zink_freedreno" ]] || [[ "$termux_hw_answer" == "freedreno_kgsl" ]] || [[ $termux_hw_answer == "zink_with_mesa" ]] || [[ $termux_hw_answer == "zink_with_mesa_zink" ]]; then
		sed -i "/if ! \$use_nogpu; then/,/fi/ {/if \$use_debug; then/,/fi/d}" "$TERMUX_PREFIX/bin/tx11start"
		sed -i "s/^[[:space:]]*&[[:space:]]*$/ /" "$TERMUX_PREFIX/bin/vncstart"
	fi

	if [[ "$exp_termux_vulkan_hw_answer" != "skip" ]]; then
		disable_vblank_mode

		if [[ "$installed_browser" == "chromium" ]] || [[ "$installed_browser" == "all" ]]; then
			sed -i "s|Exec=$TERMUX_PREFIX/bin/chromium-browser %U|Exec=$TERMUX_PREFIX/bin/chromium-browser --enable-features=Vulkan %U|" "$TERMUX_PREFIX/share/applications/chromium.desktop"
		fi

		if [[ "$installed_ide" == "code" ]] || [[ "$installed_ide" == "all" ]]; then
			sed -i "s|$TERMUX_PREFIX/bin/code-oss|$TERMUX_PREFIX/bin/code-oss --enable-features=Vulkan|g" "$TERMUX_PREFIX"/share/applications/code-oss*
		fi
	fi

	# some fixes for gnome and cinnamon desktop
	if [[ "$de_name" == "gnome" ]] || [[ "$de_name" == "cinnamon" ]]; then
		sed -i "s|<policy user=\".*\">|<policy user=\"$(whoami)\">|" "$TERMUX_PREFIX/share/dbus-1/system.d/org.freedesktop.UPower.conf"
		if [[ "$de_name" == "gnome" ]]; then
			cat <<-EOF >"$TERMUX_PREFIX/share/gnome-session/sessions/minimal.session"
				[GNOME Session]
				Name=Minimal GNOME
				RequiredComponents=org.gnome.Shell;org.gnome.SettingsDaemon.A11ySettings;org.gnome.SettingsDaemon.Color;org.gnome.SettingsDaemon.Datetime;org.gnome.SettingsDaemon.Housekeeping;org.gnome.SettingsDaemon.Keyboard;org.gnome.SettingsDaemon.Sound;
				DefaultProvider-wm=gnome-shell
				DesktopName=GNOME
			EOF
			cat <<-EOF >"$TERMUX_PREFIX/bin/gnome-session-minimal"
				rm -rf $TERMUX_PREFIX/var/run/dbus/pid
				dbus-launch --config-file $TERMUX_PREFIX/share/dbus-1/system.conf
				UPOWER_CONF_FILE_NAME=$TERMUX_PREFIX/etc/UPower/UPower.conf $TERMUX_PREFIX/libexec/upowerd -d &
				gnome-session --session=minimal \$@
			EOF
			chmod +x "$TERMUX_PREFIX/bin/gnome-session-minimal"
		fi
	fi
}

# add the basic details into a config file
function print_basic_details() {
	local net_condition
	local country
	net_condition="$(getprop gsm.network.type)"
	country="$(getprop gsm.sim.operator.iso-country)"
	if [[ -f "$CONFIG_FILE" ]]; then
		check_and_backup "$CONFIG_FILE"
	fi
	cat <<-EOF >"$CONFIG_FILE"
		####################################
		########## Termux Desktop ##########
		####################################

		########################
		#  -:Device Details:-  #
		########################
		#
		# Termux Version: ${TERMUX_VERSION}-${TERMUX_APK_RELEASE}
		# Device Model: $MODEL
		# Android Version: $ANDROID_VERSION
		# Free Space: $FREE_SPACE
		# Total Ram: $TOTAL_RAM
		# Architecture: $APP_ARCH
		# System CPU Architecture: $SUPPORTED_ARCH
		# Processor: $PROCESSOR_BRAND_NAME $PROCESSOR_NAME
		# GPU: $GPU_NAME
		# Network Condition: $net_condition
		# Country: $country
		#
		########################

		##### Please don't modify this file otherwise some functions won't work #####

	EOF
}

function add_installer() {
	if [[ ! -e "$TERMUX_PREFIX/bin/setup-termux-desktop" ]]; then
		print_msg "Adding setup-termux-desktop installer to bin"
		download_file "$TERMUX_PREFIX/bin/setup-termux-desktop" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/setup-termux-desktop"
		chmod +x "$TERMUX_PREFIX/bin/setup-termux-desktop"
	fi
}

#########################################################################
#
# Update Task
#
#########################################################################

# check for the changes in the installer file
function check_for_update_and_update_installer() {
	if [[ -e "$TERMUX_PREFIX/bin/setup-termux-desktop" ]]; then
		banner
		print_msg "Checking for update..."
		echo

		check_and_create_directory "$TERMUX_DESKTOP_PATH"
		local current_script_hash
		local update_installer
		current_script_hash=$(curl -sL $REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/setup-termux-desktop | sha256sum | cut -d ' ' -f 1)
		local local_script_hash
		local_script_hash=$(basename "$(sha256sum "$TERMUX_PREFIX/bin/setup-termux-desktop" | cut -d ' ' -f 1)")

		if [[ "$local_script_hash" != "$current_script_hash" ]]; then
			confirmation_y_or_n "You are using an old installer. Do you want to update it to the latest version" update_installer

			if [[ "$update_installer" == "y" ]]; then
				check_and_create_directory "$TERMUX_PREFIX/etc/termux-desktop"
				mv "$TERMUX_PREFIX/bin/setup-termux-desktop" "$TERMUX_PREFIX/etc/termux-desktop/"
				check_and_backup "$TERMUX_PREFIX/etc/termux-desktop/setup-termux-desktop"
				add_installer
				add_common_function
				unset local_script_hash
				local new_local_script_hash
				new_local_script_hash=$(basename "$(sha256sum "$TERMUX_PREFIX/bin/setup-termux-desktop" | cut -d ' ' -f 1)")
				if [[ "$new_local_script_hash" == "$current_script_hash" ]]; then
					print_msg "Installer updated successfully"
					check_and_delete "$TERMUX_DESKTOP_PATH/skip_update_checkup"
					exit 0
				else
					print_msg "Failed to update the installer"
					exit 0
				fi
			elif [[ "$update_installer" == "n" ]]; then
				print_msg "Keeping the old installer"
				check_and_create_directory "$TERMUX_DESKTOP_PATH"
				touch "$TERMUX_DESKTOP_PATH/skip_update_checkup"
				exit 0
			fi
		else
			print_msg "${BOLD}Great, you are using the latest installer"
		fi
	fi
}

function check_installer_status() {
	if [[ -e "$TERMUX_PREFIX/bin/setup-termux-desktop" ]]; then
		if [[ ! -e "$TERMUX_DESKTOP_PATH/skip_update_checkup" ]]; then
			check_for_update_and_update_installer
		else
			print_msg "${BOLD}Update check skipped"
			print_msg "${BOLD}Use ${C}--update ${G}to force update check"
		fi
	fi
}

function check_for_appstore_update() {
	print_msg "Checking for appstore updates..."
	echo
	appstore --update
}

#########################################################################
#
# Reset Changes
#
#########################################################################

function reset_changes() {
	if [[ ! -e "$CONFIG_FILE" ]]; then
		echo -e "${C} It looks like you haven't installed the desktop yet.\n Please install the desktop first.${NC}"
		exit 1
	else
		read_conf
		banner
		print_msg "Removing $de_name Config..."
		set_config_dir
		check_and_delete "${config_dirs[@]}"
		get_shellrc_path

		if [[ "$terminal_utility_setup_answer" == "y" ]]; then
			check_and_delete "$TERMUX_PREFIX/etc/motd.sh $TERMUX_HOME/.termux $TERMUX_HOME/.fonts/font.ttf $TERMUX_HOME/.termux/colors.properties"
			termux-reload-settings
			check_and_restore "$TERMUX_PREFIX/etc/motd"
			termux-reload-settings
			check_and_restore "$TERMUX_PREFIX/etc/motd-playstore"
			check_and_restore "$TERMUX_PREFIX/etc/motd.sh"
			termux-reload-settings
			check_and_restore "$TERMUX_HOME/.termux/colors.properties"
			# shellcheck disable=SC2164
			cd "$TERMUX_PREFIX/share/zsh/site-functions"
			check_and_delete "_add2menu _distro _setup-termux-desktop _tx11start _tx11stop _vncstart _vncstop"
			# shellcheck disable=SC2164
			cd "$TERMUX_PREFIX/share/bash-completion/completions"
			check_and_delete "add2menu distro setup-termux-desktop tx11start tx11stop vncstart vncstop"
			# shellcheck disable=SC2164
			cd "$TERMUX_HOME"
			if grep -q "motd.sh$" "$TERMUX_PREFIX/etc/termux-login.sh"; then
				sed -i "s|.*motd\.sh$|# |" "$TERMUX_PREFIX/etc/termux-login.sh"
				termux-reload-settings
			fi
			rm "$TERMUX_PREFIX/share/applications/wine-*.desktop" >/dev/null 2>&1
			check_and_delete "$TERMUX_DESKTOP_PATH"
			check_and_delete "$TERMUX_PREFIX/bin/tx11start $TERMUX_PREFIX/bin/tx11stop $TERMUX_PREFIX/bin/vncstop $TERMUX_PREFIX/bin/vncstart $TERMUX_PREFIX/bin/gui $TERMUX_PREFIX/bin/pdrun"
		fi

		check_and_delete "$TERMUX_HOME/Music"
		check_and_delete "$TERMUX_HOME/Downloads"
		check_and_delete "$TERMUX_HOME/Desktop"
		check_and_delete "$TERMUX_HOME/Pictures"
		check_and_delete "$TERMUX_HOME/Videos"

		if [[ "$shell_name" == "zsh" ]]; then
			check_and_delete "$TERMUX_HOME/.oh-my-zsh"
		fi

		check_and_delete "$shell_rc_file"
		check_and_restore "$shell_rc_file"
		print_success "${BOLD}Reset successful. Now restart Termux."
	fi
}

#########################################################################
#
# Call Functions
#
#########################################################################
check_termux
detect_package_manager
if [[ -z "$1" ]] || [[ "$1" == "--install" ]] || [[ "$1" == "-i" ]]; then
	check_installer_status "$1"
fi
current_path=$(pwd)
get_termux_arch
function install_termux_desktop() {
	banner
	update_sys
	cleanup_cache
	termux-wake-lock
	install_required_packages
	recheck_basic_packages
	if [[ "$1" != "--local-config" && "$1" != "--config" && "$1" != "-config" ]]; then
		print_recomended_msg
	fi
	if [[ "$1" != "--local-config" && "$1" != "--config" && "$1" != "-config" ]]; then
		questions_install_type
		if [[ "$install_type_answer" == "1" ]]; then
			if [[ "$distro_add_answer" == "y" ]]; then
				distro_questions
			fi

			if [[ "$enable_hw_acc" == "y" ]]; then
				setup_device_gpu_model
				hw_questions
			fi
		fi
	fi
	if [[ "$1" == "--local-config" ]] || [[ "$1" == "--config" ]] || [[ "$1" == "-config" ]]; then
		download_file "${current_path}/styles.md" "$REPO_RAW_URL/refs/heads/$REPO_BRANCH_MAIN/docs/${de_name}_styles.md"
		style_name=$(grep -oP "^## $style_answer\..+?(?=(\n## \d+\.|\Z))" "${current_path}/styles.md" | sed -e "s/^## $style_answer\. //" -e "s/:$//" -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
		check_and_delete "${current_path}/styles.md"
	fi
	print_conf_info
	check_and_create_directory "${TERMUX_DESKTOP_PATH}"
	log_debug "$CONFIG_FILE"
	print_basic_details
	setup_necessary_permissions
	setup_shell
	setup_fonts
	install_desktop
	browser_installer
	ide_installer
	media_player_installer
	photo_editor_installer
	setup_wine
	if [[ "$style_answer" == "0" ]]; then
		banner
		print_msg "${BOLD}Configuring Stock $de_name Style..."
		echo
		print_to_config "style_answer"
		ext_setup_for_stock
	else
		setup_config
	fi
	ext_wall_setup
	banner
	add_common_function
	distro_container_setup
	gui_launcher
	terminal_utility_setup
	if [[ "$selected_distro_type" == "proot" ]]; then
		install_termux_desktop_appstore
	fi
	add_to_autostart
	check_desktop_process
	install_fm_tools
	add_usb_auto_mount
	add_auto_completion
	some_fixes
	cleanup_cache
	termux-wake-unlock
	add_installer
	notes
	log_debug "$(cat "$CONFIG_FILE")"
}

function show_help() {
	cat <<-EOF
		--debug                 - create a log file
		-i,--install            - start installation
		-r,--remove             - remove termux desktop
		-c,--change             - change some previous configuration
		-ri,--reinstall         - reinstall some previously install stuff
		--reset                 - reset all changes made by this script without uninstalling any package
		--local-config,-config  - start the installation from pre made config file
		-h,--help               - show help
	EOF
}

function show_change_help() {
	cat <<-EOF
		options you can use with --change
		style      - change installed style
		pd,distro  - change installed linux distro container
		hw,hwa     - change hardware acceleration method
		autostart  - change autostart behaviour
		display    - change termux:x11 display port
		de,wm      - switch between diffreent desktop environment or window manager
		h,help     - show help

		example uses : --change style
	EOF
}

function show_reinstall_help() {
	cat <<-EOF
		options you can use with --reinstall
		icons      - reinstall icons pack
		themes     - reinstall themes pack
		config     - reinstall config
		h,help     - show help

		example uses : --reinstall icons
		example uses : --reinstall icons,themes...etc to reinstall them at once
	EOF
}

if [[ $1 == "--debug" ]]; then
	trap debug_msg debug
	shift
fi

case $1 in
--remove | -r | --uninstall)
	remove_termux_desktop
	;;
--install | -i | in)
	install_termux_desktop "$1"
	;;
--change | -c)
	case $2 in
	style)
		# shellcheck disable=SC2034
		CALL_FROM_CHANGE_STYLE=true
		change_style
		;;
	distro | pd)
		# shellcheck disable=SC2034
		CALL_FROM_CHANGE_DISTRO=true
		change_distro
		;;
	hw | hwa)
		change_hw
		;;
	autostart)
		change_autostart
		;;
	display)
		change_display
		;;
	de | wm | desktop | winm | wim)
		change_de
		;;
	h | help | -h | --help)
		show_change_help
		;;
	*)
		print_failed "${BOLD} Invalid option: ${C}$2"
		print_msg "Use --change help   - to show help"
		;;
	esac
	;;
--reinstall | -ri)
	IFS=',' read -ra OPTIONS <<<"$2"
	for option in "${OPTIONS[@]}"; do
		case $option in
		icons)
			reinstall_icons
			;;
		themes)
			reinstall_themes
			;;
		config)
			reinstall_config
			;;
		h | help | -h | --help)
			show_reinstall_help
			exit
			;;
		*)
			print_failed "${BOLD} Invalid option: ${C}$option"
			print_msg "Use --reinstall help   - show help"
			;;
		esac
	done
	;;
--update)
	check_for_update_and_update_installer "$1"
	check_for_appstore_update
	;;
--help | -h)
	show_help
	;;
--reset)
	reset_changes
	;;
--local-config | --config | -config)
	print_recomended_msg
	load_local_config "$2"
	install_termux_desktop "$1"
	;;
*)
	if [[ -n "$1" ]]; then
		print_failed "${BOLD} Invalid option: ${C}$1"
		show_help
	else
		install_termux_desktop "$1"
	fi
	check_termux
	;;
esac
